@lambdacurry/arbor 0.14.4 → 0.14.6
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 +158 -8
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -38,6 +38,7 @@ var ERROR_REASONS = new Set([
|
|
|
38
38
|
"authorization.denied",
|
|
39
39
|
"resource.not_found",
|
|
40
40
|
"conflict.state",
|
|
41
|
+
"conflict.computer_recipe",
|
|
41
42
|
"limit.exceeded",
|
|
42
43
|
"provider.timeout",
|
|
43
44
|
"provider.failure",
|
|
@@ -1581,12 +1582,55 @@ var githubWebhookDeliveries = sqliteTable("github_webhook_deliveries", {
|
|
|
1581
1582
|
var threadComputers = sqliteTable("thread_computers", {
|
|
1582
1583
|
id: text("id").primaryKey(),
|
|
1583
1584
|
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1585
|
+
generation: integer("generation").notNull().default(1),
|
|
1584
1586
|
provider: text("provider").$type().notNull(),
|
|
1587
|
+
backend: text("backend").$type().notNull().default("worker-shell"),
|
|
1588
|
+
containerProfile: text("container_profile"),
|
|
1589
|
+
repositories: text("repositories", { mode: "json" }).$type().notNull().default([]),
|
|
1590
|
+
setupScriptConfigured: integer("setup_script_configured", { mode: "boolean" }).notNull().default(false),
|
|
1591
|
+
configKey: text("config_key").notNull().default("legacy"),
|
|
1592
|
+
configRevision: text("config_revision").notNull().default("legacy"),
|
|
1593
|
+
predecessorComputerId: text("predecessor_computer_id"),
|
|
1594
|
+
successorComputerId: text("successor_computer_id"),
|
|
1595
|
+
restoredFromSnapshotId: text("restored_from_snapshot_id"),
|
|
1585
1596
|
currentSnapshotId: text("current_snapshot_id"),
|
|
1586
1597
|
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1587
1598
|
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1588
1599
|
createdAt: ts("created_at").notNull()
|
|
1589
|
-
}, (t) => ({
|
|
1600
|
+
}, (t) => ({
|
|
1601
|
+
threadIdx: index("thread_computers_thread_idx").on(t.threadId, t.generation),
|
|
1602
|
+
generationIdx: uniqueIndex("thread_computers_generation_idx").on(t.threadId, t.generation)
|
|
1603
|
+
}));
|
|
1604
|
+
var threadComputerHeads = sqliteTable("thread_computer_heads", {
|
|
1605
|
+
threadId: text("thread_id").primaryKey().references(() => threads.id),
|
|
1606
|
+
activeComputerId: text("active_computer_id").notNull().unique().references(() => threadComputers.id),
|
|
1607
|
+
updatedByProfileId: text("updated_by_profile_id").notNull().references(() => profiles.id),
|
|
1608
|
+
updatedExecutionContextId: text("updated_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1609
|
+
updatedAt: ts("updated_at").notNull()
|
|
1610
|
+
});
|
|
1611
|
+
var computerReprovisions = sqliteTable("computer_reprovisions", {
|
|
1612
|
+
id: text("id").primaryKey(),
|
|
1613
|
+
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1614
|
+
actorProfileId: text("actor_profile_id").notNull().references(() => profiles.id),
|
|
1615
|
+
executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
|
|
1616
|
+
idempotencyKey: text("idempotency_key").notNull(),
|
|
1617
|
+
targetConfigKey: text("target_config_key").notNull(),
|
|
1618
|
+
reason: text("reason").notNull(),
|
|
1619
|
+
status: text("status").$type().notNull().default("pending"),
|
|
1620
|
+
oldComputerId: text("old_computer_id").notNull().references(() => threadComputers.id),
|
|
1621
|
+
newComputerId: text("new_computer_id").references(() => threadComputers.id),
|
|
1622
|
+
sourceSessionId: text("source_session_id"),
|
|
1623
|
+
targetSessionId: text("target_session_id"),
|
|
1624
|
+
checkpointOutcome: text("checkpoint_outcome").$type().notNull().default("not_needed"),
|
|
1625
|
+
restorationOutcome: text("restoration_outcome").$type().notNull().default("not_needed"),
|
|
1626
|
+
restoredSnapshotId: text("restored_snapshot_id"),
|
|
1627
|
+
failureCode: text("failure_code"),
|
|
1628
|
+
createdAt: ts("created_at").notNull(),
|
|
1629
|
+
completedAt: ts("completed_at")
|
|
1630
|
+
}, (t) => ({
|
|
1631
|
+
idempotencyIdx: uniqueIndex("computer_reprovisions_idempotency_idx").on(t.threadId, t.actorProfileId, t.idempotencyKey),
|
|
1632
|
+
threadIdx: index("computer_reprovisions_thread_idx").on(t.threadId, t.createdAt)
|
|
1633
|
+
}));
|
|
1590
1634
|
var computerSessions = sqliteTable("computer_sessions", {
|
|
1591
1635
|
id: text("id").primaryKey(),
|
|
1592
1636
|
computerId: text("computer_id").notNull().references(() => threadComputers.id),
|
|
@@ -1864,6 +1908,7 @@ var appBundles = sqliteTable("app_bundles", {
|
|
|
1864
1908
|
}).$type(),
|
|
1865
1909
|
runtimeEntrypoint: text("runtime_entrypoint").$type().notNull(),
|
|
1866
1910
|
capabilityRequirements: text("capability_requirements", { mode: "json" }).$type().notNull().default([]),
|
|
1911
|
+
runtimeConfigRequirements: text("runtime_config_requirements", { mode: "json" }).$type().notNull().default([]),
|
|
1867
1912
|
stateSchemaVersion: integer("state_schema_version").notNull().default(0),
|
|
1868
1913
|
stateCompatibleFrom: integer("state_compatible_from").notNull().default(0),
|
|
1869
1914
|
stateCompatibleThrough: integer("state_compatible_through").notNull().default(0),
|
|
@@ -1930,6 +1975,22 @@ var secretBindings = sqliteTable("secret_bindings", {
|
|
|
1930
1975
|
appNameUq: uniqueIndex("secret_bindings_app_name_uq").on(t.appId, t.bindingName),
|
|
1931
1976
|
secretIdx: index("secret_bindings_secret_idx").on(t.secretId, t.status)
|
|
1932
1977
|
}));
|
|
1978
|
+
var appRuntimeVars = sqliteTable("app_runtime_vars", {
|
|
1979
|
+
id: text("id").primaryKey(),
|
|
1980
|
+
appId: text("app_id").notNull().references(() => apps.id),
|
|
1981
|
+
name: text("name").notNull(),
|
|
1982
|
+
value: text("value").notNull(),
|
|
1983
|
+
revision: integer("revision").notNull().default(1),
|
|
1984
|
+
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1985
|
+
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1986
|
+
createdAt: ts("created_at").notNull(),
|
|
1987
|
+
updatedByProfileId: text("updated_by_profile_id").notNull().references(() => profiles.id),
|
|
1988
|
+
updatedExecutionContextId: text("updated_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1989
|
+
updatedAt: ts("updated_at").notNull()
|
|
1990
|
+
}, (t) => ({
|
|
1991
|
+
appNameUq: uniqueIndex("app_runtime_vars_app_name_uq").on(t.appId, t.name),
|
|
1992
|
+
appIdx: index("app_runtime_vars_app_idx").on(t.appId)
|
|
1993
|
+
}));
|
|
1933
1994
|
var appDeployments = sqliteTable("app_deployments", {
|
|
1934
1995
|
id: text("id").primaryKey(),
|
|
1935
1996
|
appId: text("app_id").notNull().references(() => apps.id),
|
|
@@ -16576,6 +16637,15 @@ var computerConfig = exports_external.looseObject({
|
|
|
16576
16637
|
setupScript: nullableString,
|
|
16577
16638
|
repositories: exports_external.array(exports_external.string())
|
|
16578
16639
|
});
|
|
16640
|
+
var redactedComputerRecipe = exports_external.looseObject({
|
|
16641
|
+
provider: exports_external.string(),
|
|
16642
|
+
backend: exports_external.enum(["worker-shell", "container"]),
|
|
16643
|
+
containerProfile: nullableString,
|
|
16644
|
+
repositories: exports_external.array(exports_external.string()),
|
|
16645
|
+
setupScriptConfigured: exports_external.boolean(),
|
|
16646
|
+
configRevision: exports_external.string(),
|
|
16647
|
+
layers: exports_external.array(exports_external.looseObject({ scope: exports_external.string() }))
|
|
16648
|
+
});
|
|
16579
16649
|
var computerConfigLayer = exports_external.looseObject({
|
|
16580
16650
|
id,
|
|
16581
16651
|
scope: exports_external.string(),
|
|
@@ -16903,11 +16973,20 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
16903
16973
|
}),
|
|
16904
16974
|
get_computer: exports_external.looseObject({
|
|
16905
16975
|
threadId: id,
|
|
16906
|
-
config:
|
|
16907
|
-
|
|
16976
|
+
config: redactedComputerRecipe,
|
|
16977
|
+
compatibility: exports_external.looseObject({
|
|
16978
|
+
state: exports_external.enum(["ready", "stale_config", "backend_mismatch", "replacement_required"]),
|
|
16979
|
+
reason: exports_external.string(),
|
|
16980
|
+
effectiveRecipe: redactedComputerRecipe,
|
|
16981
|
+
materializedRecipe: redactedComputerRecipe.nullable()
|
|
16982
|
+
}),
|
|
16983
|
+
topicBase: jsonObject.nullable(),
|
|
16908
16984
|
computer: jsonObject.nullable(),
|
|
16985
|
+
activeGenerationId: id.nullable(),
|
|
16986
|
+
generations: exports_external.array(jsonObject),
|
|
16909
16987
|
sessions: exports_external.array(jsonObject),
|
|
16910
|
-
lineage: exports_external.array(
|
|
16988
|
+
lineage: exports_external.array(jsonObject),
|
|
16989
|
+
reprovisions: exports_external.array(jsonObject)
|
|
16911
16990
|
}),
|
|
16912
16991
|
publish_topic_computer: exports_external.looseObject({
|
|
16913
16992
|
published: exports_external.boolean(),
|
|
@@ -17141,6 +17220,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17141
17220
|
app_fetch: appInvocationResponse,
|
|
17142
17221
|
app_request: appInvocationResponse,
|
|
17143
17222
|
app_create: app2,
|
|
17223
|
+
app_config_apply: exports_external.object({ appId: id, dryRun: exports_external.boolean(), changes: exports_external.array(jsonObject) }),
|
|
17144
17224
|
app_deploy: exports_external.looseObject({
|
|
17145
17225
|
deployment,
|
|
17146
17226
|
activated: exports_external.boolean(),
|
|
@@ -17181,6 +17261,19 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17181
17261
|
materialized: checkpoint.nullable(),
|
|
17182
17262
|
runtime: jsonObject
|
|
17183
17263
|
}),
|
|
17264
|
+
computer_reprovision: exports_external.looseObject({
|
|
17265
|
+
reprovisionId: id,
|
|
17266
|
+
threadId: id,
|
|
17267
|
+
status: exports_external.string(),
|
|
17268
|
+
oldComputerId: id,
|
|
17269
|
+
newComputerId: id.nullable(),
|
|
17270
|
+
computerSessionId: id.nullable(),
|
|
17271
|
+
checkpointOutcome: exports_external.string(),
|
|
17272
|
+
restorationOutcome: exports_external.string(),
|
|
17273
|
+
restoredSnapshotId: id.nullable(),
|
|
17274
|
+
failureCode: exports_external.string().nullable(),
|
|
17275
|
+
reason: exports_external.string()
|
|
17276
|
+
}),
|
|
17184
17277
|
computer_exec: exports_external.looseObject({
|
|
17185
17278
|
stdout: exports_external.string().optional(),
|
|
17186
17279
|
stderr: exports_external.string().optional(),
|
|
@@ -17412,6 +17505,7 @@ var MCP_TOOL_ANNOTATIONS = {
|
|
|
17412
17505
|
app_fetch: readOnly,
|
|
17413
17506
|
app_request: destructive,
|
|
17414
17507
|
app_create: additive,
|
|
17508
|
+
app_config_apply: idempotent,
|
|
17415
17509
|
app_deploy: idempotent,
|
|
17416
17510
|
app_activate: additive,
|
|
17417
17511
|
app_rollback: additive,
|
|
@@ -17421,6 +17515,7 @@ var MCP_TOOL_ANNOTATIONS = {
|
|
|
17421
17515
|
app_archive: additive,
|
|
17422
17516
|
charter: destructive,
|
|
17423
17517
|
computer_open: additive,
|
|
17518
|
+
computer_reprovision: destructiveIdempotent,
|
|
17424
17519
|
computer_exec: destructiveOpenWorld,
|
|
17425
17520
|
computer_status: readOnly,
|
|
17426
17521
|
computer_verify: openWorld,
|
|
@@ -17779,6 +17874,19 @@ var ACTION_DEFINITIONS = [
|
|
|
17779
17874
|
toolset: "loop",
|
|
17780
17875
|
run: forward("computer_runtime.open")
|
|
17781
17876
|
},
|
|
17877
|
+
{
|
|
17878
|
+
name: "computer_reprovision",
|
|
17879
|
+
title: "Replace a Thread computer",
|
|
17880
|
+
description: "Explicitly replace an incompatible active Computer generation from the Thread's effective recipe. The old generation remains authoritative unless the successor restores supported state and passes health. Same-provider worker-shell→container migration is supported; container→worker-shell and cross-provider migration fail explicitly. Reuse one idempotencyKey only for the same replacement request.",
|
|
17881
|
+
inputSchema: {
|
|
17882
|
+
threadId: exports_external.string().describe("the Thread whose active Computer generation is replaced, thr_…"),
|
|
17883
|
+
idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this ONE replacement request; reuse it unchanged for retries"),
|
|
17884
|
+
reason: exports_external.string().min(1).max(500).describe("concise auditable reason for replacing the active generation")
|
|
17885
|
+
},
|
|
17886
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
17887
|
+
toolset: "loop",
|
|
17888
|
+
run: forward("computer_runtime.reprovision")
|
|
17889
|
+
},
|
|
17782
17890
|
{
|
|
17783
17891
|
name: "computer_exec",
|
|
17784
17892
|
title: "Run a command",
|
|
@@ -17968,6 +18076,7 @@ var ACTION_DEFINITIONS = [
|
|
|
17968
18076
|
stateSchemaVersion: exports_external.number().int().min(0).optional().describe("durable schema this release writes; default 0"),
|
|
17969
18077
|
stateCompatibleFrom: exports_external.number().int().min(0).optional().describe("oldest durable schema this code can open"),
|
|
17970
18078
|
stateCompatibleThrough: exports_external.number().int().min(0).optional().describe("newest durable schema this code can open"),
|
|
18079
|
+
runtimeConfigRequirements: exports_external.array(exports_external.object({ name: exports_external.string().min(1).max(64), kind: exports_external.enum(["var", "secret"]) })).optional().describe("required runtime config keys and kinds; values are never part of the AppBundle"),
|
|
17971
18080
|
idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this one logical bundle publication")
|
|
17972
18081
|
},
|
|
17973
18082
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
@@ -17988,7 +18097,7 @@ var ACTION_DEFINITIONS = [
|
|
|
17988
18097
|
{
|
|
17989
18098
|
name: "get_computer",
|
|
17990
18099
|
title: "Read a Thread computer",
|
|
17991
|
-
description: "Read a Thread's effective recipe,
|
|
18100
|
+
description: "Read a Thread's redacted effective recipe, active materialized generation, compatibility state, historical generation lineage, current Topic/Thread snapshot refs, recent attachment receipts, and replacement outcomes. Recipe metadata includes provider/backend/profile/repositories/config revision and whether setup is configured, never setup content or credentials. This is durable Arbor protocol state, not live process/presence status.",
|
|
17992
18101
|
inputSchema: {
|
|
17993
18102
|
threadId: exports_external.string().describe("the Thread, thr_…"),
|
|
17994
18103
|
lineageLimit: exports_external.number().int().min(1).max(100).optional().describe("recent receipts/lineage rows (default 20)")
|
|
@@ -19198,6 +19307,22 @@ var ACTION_DEFINITIONS = [
|
|
|
19198
19307
|
toolset: "apps",
|
|
19199
19308
|
run: forward("app.create")
|
|
19200
19309
|
},
|
|
19310
|
+
{
|
|
19311
|
+
name: "app_config_apply",
|
|
19312
|
+
title: "Apply App runtime config",
|
|
19313
|
+
description: "Declaratively apply the complete typed runtime config for one App. var stores an ordinary runtime value; secret references an existing Arbor Secret without accepting or returning secret material. Dry-run performs the same validation and returns create/update/delete/no-op actions without mutating.",
|
|
19314
|
+
inputSchema: {
|
|
19315
|
+
appId: exports_external.string().describe("target App, app_…"),
|
|
19316
|
+
config: exports_external.record(exports_external.string(), exports_external.discriminatedUnion("kind", [
|
|
19317
|
+
exports_external.object({ kind: exports_external.literal("var"), value: exports_external.string().max(16384) }),
|
|
19318
|
+
exports_external.object({ kind: exports_external.literal("secret"), secretId: exports_external.string() })
|
|
19319
|
+
])).describe("complete desired runtime config object keyed by environment variable name"),
|
|
19320
|
+
dryRun: exports_external.boolean().optional().describe("validate and plan without mutating")
|
|
19321
|
+
},
|
|
19322
|
+
surfaces: ["mcp", "cli"],
|
|
19323
|
+
toolset: "apps",
|
|
19324
|
+
run: forward("app.config_apply")
|
|
19325
|
+
},
|
|
19201
19326
|
{
|
|
19202
19327
|
name: "app_deploy",
|
|
19203
19328
|
title: "Prepare an App deployment",
|
|
@@ -19506,6 +19631,11 @@ function parseErrorDetails(value) {
|
|
|
19506
19631
|
};
|
|
19507
19632
|
}
|
|
19508
19633
|
}
|
|
19634
|
+
if (typeof raw.compatibilityState === "string") {
|
|
19635
|
+
details.compatibilityState = raw.compatibilityState;
|
|
19636
|
+
}
|
|
19637
|
+
if (typeof raw.suggestedAction === "string")
|
|
19638
|
+
details.suggestedAction = raw.suggestedAction;
|
|
19509
19639
|
return details;
|
|
19510
19640
|
}
|
|
19511
19641
|
function detailsForError(err) {
|
|
@@ -19748,6 +19878,9 @@ function kindOf(node) {
|
|
|
19748
19878
|
return "array";
|
|
19749
19879
|
case "boolean":
|
|
19750
19880
|
return "boolean";
|
|
19881
|
+
case "object":
|
|
19882
|
+
case "record":
|
|
19883
|
+
return "json";
|
|
19751
19884
|
default:
|
|
19752
19885
|
return "string";
|
|
19753
19886
|
}
|
|
@@ -19756,7 +19889,7 @@ function acceptedFlags(inputSchema) {
|
|
|
19756
19889
|
const out = new Set;
|
|
19757
19890
|
for (const spec of flagsForSchema(inputSchema)) {
|
|
19758
19891
|
out.add(spec.flag);
|
|
19759
|
-
if (spec.kind === "string")
|
|
19892
|
+
if (spec.kind === "string" || spec.kind === "json")
|
|
19760
19893
|
out.add(`${spec.flag}-file`);
|
|
19761
19894
|
}
|
|
19762
19895
|
return out;
|
|
@@ -19792,7 +19925,7 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19792
19925
|
const primary = primaryPositionalField(inputSchema);
|
|
19793
19926
|
const input = {};
|
|
19794
19927
|
for (const spec of flagsForSchema(inputSchema)) {
|
|
19795
|
-
if (spec.kind === "string") {
|
|
19928
|
+
if (spec.kind === "string" || spec.kind === "json") {
|
|
19796
19929
|
const fileSrc = lastValue(flags[`${spec.flag}-file`]);
|
|
19797
19930
|
if (fileSrc !== undefined) {
|
|
19798
19931
|
if (flags[spec.flag] !== undefined) {
|
|
@@ -19800,7 +19933,16 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19800
19933
|
}
|
|
19801
19934
|
if (fileSrc === true)
|
|
19802
19935
|
throw new UsageError(`--${spec.flag}-file expects a path (or - for stdin)`);
|
|
19803
|
-
|
|
19936
|
+
const sourced = readTextSource(String(fileSrc));
|
|
19937
|
+
if (spec.kind === "json") {
|
|
19938
|
+
try {
|
|
19939
|
+
input[spec.field] = JSON.parse(sourced);
|
|
19940
|
+
} catch {
|
|
19941
|
+
throw new UsageError(`--${spec.flag}-file must contain valid JSON`);
|
|
19942
|
+
}
|
|
19943
|
+
} else {
|
|
19944
|
+
input[spec.field] = sourced;
|
|
19945
|
+
}
|
|
19804
19946
|
continue;
|
|
19805
19947
|
}
|
|
19806
19948
|
}
|
|
@@ -19864,6 +20006,14 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19864
20006
|
input[spec.field] = out;
|
|
19865
20007
|
break;
|
|
19866
20008
|
}
|
|
20009
|
+
case "json": {
|
|
20010
|
+
try {
|
|
20011
|
+
input[spec.field] = JSON.parse(String(lastValue(raw)));
|
|
20012
|
+
} catch {
|
|
20013
|
+
throw new UsageError(`--${spec.flag} must be valid JSON`);
|
|
20014
|
+
}
|
|
20015
|
+
break;
|
|
20016
|
+
}
|
|
19867
20017
|
case "boolean": {
|
|
19868
20018
|
const v = lastValue(raw);
|
|
19869
20019
|
input[spec.field] = v === true ? true : v !== "false";
|
package/package.json
CHANGED