@lambdacurry/arbor 0.14.5 → 0.15.0
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 +73 -12
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -1625,6 +1625,7 @@ var computerReprovisions = sqliteTable("computer_reprovisions", {
|
|
|
1625
1625
|
restorationOutcome: text("restoration_outcome").$type().notNull().default("not_needed"),
|
|
1626
1626
|
restoredSnapshotId: text("restored_snapshot_id"),
|
|
1627
1627
|
failureCode: text("failure_code"),
|
|
1628
|
+
failureDetail: text("failure_detail"),
|
|
1628
1629
|
createdAt: ts("created_at").notNull(),
|
|
1629
1630
|
completedAt: ts("completed_at")
|
|
1630
1631
|
}, (t) => ({
|
|
@@ -1908,6 +1909,7 @@ var appBundles = sqliteTable("app_bundles", {
|
|
|
1908
1909
|
}).$type(),
|
|
1909
1910
|
runtimeEntrypoint: text("runtime_entrypoint").$type().notNull(),
|
|
1910
1911
|
capabilityRequirements: text("capability_requirements", { mode: "json" }).$type().notNull().default([]),
|
|
1912
|
+
runtimeConfigRequirements: text("runtime_config_requirements", { mode: "json" }).$type().notNull().default([]),
|
|
1911
1913
|
stateSchemaVersion: integer("state_schema_version").notNull().default(0),
|
|
1912
1914
|
stateCompatibleFrom: integer("state_compatible_from").notNull().default(0),
|
|
1913
1915
|
stateCompatibleThrough: integer("state_compatible_through").notNull().default(0),
|
|
@@ -1974,6 +1976,22 @@ var secretBindings = sqliteTable("secret_bindings", {
|
|
|
1974
1976
|
appNameUq: uniqueIndex("secret_bindings_app_name_uq").on(t.appId, t.bindingName),
|
|
1975
1977
|
secretIdx: index("secret_bindings_secret_idx").on(t.secretId, t.status)
|
|
1976
1978
|
}));
|
|
1979
|
+
var appRuntimeVars = sqliteTable("app_runtime_vars", {
|
|
1980
|
+
id: text("id").primaryKey(),
|
|
1981
|
+
appId: text("app_id").notNull().references(() => apps.id),
|
|
1982
|
+
name: text("name").notNull(),
|
|
1983
|
+
value: text("value").notNull(),
|
|
1984
|
+
revision: integer("revision").notNull().default(1),
|
|
1985
|
+
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1986
|
+
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1987
|
+
createdAt: ts("created_at").notNull(),
|
|
1988
|
+
updatedByProfileId: text("updated_by_profile_id").notNull().references(() => profiles.id),
|
|
1989
|
+
updatedExecutionContextId: text("updated_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1990
|
+
updatedAt: ts("updated_at").notNull()
|
|
1991
|
+
}, (t) => ({
|
|
1992
|
+
appNameUq: uniqueIndex("app_runtime_vars_app_name_uq").on(t.appId, t.name),
|
|
1993
|
+
appIdx: index("app_runtime_vars_app_idx").on(t.appId)
|
|
1994
|
+
}));
|
|
1977
1995
|
var appDeployments = sqliteTable("app_deployments", {
|
|
1978
1996
|
id: text("id").primaryKey(),
|
|
1979
1997
|
appId: text("app_id").notNull().references(() => apps.id),
|
|
@@ -17203,6 +17221,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17203
17221
|
app_fetch: appInvocationResponse,
|
|
17204
17222
|
app_request: appInvocationResponse,
|
|
17205
17223
|
app_create: app2,
|
|
17224
|
+
app_config_apply: exports_external.object({ appId: id, dryRun: exports_external.boolean(), changes: exports_external.array(jsonObject) }),
|
|
17206
17225
|
app_deploy: exports_external.looseObject({
|
|
17207
17226
|
deployment,
|
|
17208
17227
|
activated: exports_external.boolean(),
|
|
@@ -17310,6 +17329,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17310
17329
|
operation: exports_external.literal("clone"),
|
|
17311
17330
|
repository: exports_external.string(),
|
|
17312
17331
|
dir: exports_external.string(),
|
|
17332
|
+
credential: exports_external.enum(["caller", "arbor-managed"]),
|
|
17313
17333
|
branch: exports_external.string().optional(),
|
|
17314
17334
|
head: exports_external.string().optional(),
|
|
17315
17335
|
refs: exports_external.array(exports_external.string()).optional()
|
|
@@ -17319,6 +17339,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17319
17339
|
operation: exports_external.literal("fetch"),
|
|
17320
17340
|
repository: exports_external.string(),
|
|
17321
17341
|
dir: exports_external.string(),
|
|
17342
|
+
credential: exports_external.enum(["caller", "arbor-managed"]),
|
|
17322
17343
|
branch: exports_external.string().optional(),
|
|
17323
17344
|
head: exports_external.string().optional(),
|
|
17324
17345
|
fetchHead: exports_external.string().optional(),
|
|
@@ -17329,6 +17350,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17329
17350
|
operation: exports_external.literal("pull"),
|
|
17330
17351
|
repository: exports_external.string(),
|
|
17331
17352
|
dir: exports_external.string(),
|
|
17353
|
+
credential: exports_external.enum(["caller", "arbor-managed"]),
|
|
17332
17354
|
branch: exports_external.string().optional(),
|
|
17333
17355
|
head: exports_external.string().optional(),
|
|
17334
17356
|
before: exports_external.string().optional(),
|
|
@@ -17341,6 +17363,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17341
17363
|
operation: exports_external.literal("push"),
|
|
17342
17364
|
repository: exports_external.string(),
|
|
17343
17365
|
dir: exports_external.string(),
|
|
17366
|
+
credential: exports_external.enum(["caller", "arbor-managed"]),
|
|
17344
17367
|
branch: exports_external.string().optional(),
|
|
17345
17368
|
head: exports_external.string().optional(),
|
|
17346
17369
|
before: exports_external.string().optional(),
|
|
@@ -17487,6 +17510,7 @@ var MCP_TOOL_ANNOTATIONS = {
|
|
|
17487
17510
|
app_fetch: readOnly,
|
|
17488
17511
|
app_request: destructive,
|
|
17489
17512
|
app_create: additive,
|
|
17513
|
+
app_config_apply: idempotent,
|
|
17490
17514
|
app_deploy: idempotent,
|
|
17491
17515
|
app_activate: additive,
|
|
17492
17516
|
app_rollback: additive,
|
|
@@ -17964,13 +17988,13 @@ var ACTION_DEFINITIONS = [
|
|
|
17964
17988
|
{
|
|
17965
17989
|
name: "computer_sync",
|
|
17966
17990
|
title: "Sync an allowed repository",
|
|
17967
|
-
description: "Fetch, fast-forward pull, or push the checked-out branch of a cloned recipe repository
|
|
17991
|
+
description: "Fetch, fast-forward pull, or push the checked-out branch of a cloned recipe repository. OMIT githubToken to refresh a repository named in this computer's effective recipe with Arbor's own managed credential — Arbor rechecks the repository connection and mints a request-scoped one-repository read credential server-side, so a restored computer can reach current history with no token of yours. Managed refresh covers fetch and pull; push writes to GitHub and still takes your just-in-time collaborator token. The lightweight Computer fixes the allowlisted GitHub URL, never force-pushes or deletes refs, and neither stores nor returns either credential.",
|
|
17968
17992
|
inputSchema: {
|
|
17969
17993
|
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
17970
17994
|
repository: exports_external.string().describe("allowed owner/repository slug already cloned by computer_clone"),
|
|
17971
17995
|
operation: exports_external.enum(["fetch", "pull", "push"]).describe("network operation to perform"),
|
|
17972
|
-
githubToken: exports_external.string().min(1).describe("short-lived GitHub token
|
|
17973
|
-
githubUsername: exports_external.string().optional().describe("GitHub username; defaults to x-access-token")
|
|
17996
|
+
githubToken: exports_external.string().min(1).optional().describe("short-lived collaborator GitHub token; omit for fetch/pull to use Arbor's managed recipe credential, required for push"),
|
|
17997
|
+
githubUsername: exports_external.string().optional().describe("GitHub username for a supplied githubToken; defaults to x-access-token")
|
|
17974
17998
|
},
|
|
17975
17999
|
surfaces: ["computer-cli"],
|
|
17976
18000
|
toolset: "loop",
|
|
@@ -17979,12 +18003,12 @@ var ACTION_DEFINITIONS = [
|
|
|
17979
18003
|
{
|
|
17980
18004
|
name: "computer_fetch",
|
|
17981
18005
|
title: "Fetch an allowed repository",
|
|
17982
|
-
description:
|
|
18006
|
+
description: `Fetch remote refs for a cloned recipe repository without changing its checked-out branch or any remote ref. OMIT githubToken and Arbor refreshes it for you: it rechecks that the repository is in this computer's effective recipe and still connected, mints a request-scoped one-repository read credential server-side, spends it on this fetch alone, and returns credential: "arbor-managed" — this is the way a RESTORED computer, which deliberately holds no credential, catches up with the remote. Supply githubToken instead to fetch as the collaborator. Neither credential is stored or returned.`,
|
|
17983
18007
|
inputSchema: {
|
|
17984
18008
|
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
17985
18009
|
repository: exports_external.string().describe("allowed owner/repository slug already cloned"),
|
|
17986
|
-
githubToken: exports_external.string().min(1).describe("short-lived GitHub token
|
|
17987
|
-
githubUsername: exports_external.string().optional().describe("GitHub username; defaults to x-access-token")
|
|
18010
|
+
githubToken: exports_external.string().min(1).optional().describe("short-lived collaborator GitHub token; omit to use Arbor's managed recipe credential"),
|
|
18011
|
+
githubUsername: exports_external.string().optional().describe("GitHub username for a supplied githubToken; defaults to x-access-token")
|
|
17988
18012
|
},
|
|
17989
18013
|
surfaces: ["computer-mcp"],
|
|
17990
18014
|
toolset: "loop",
|
|
@@ -17993,12 +18017,12 @@ var ACTION_DEFINITIONS = [
|
|
|
17993
18017
|
{
|
|
17994
18018
|
name: "computer_pull",
|
|
17995
18019
|
title: "Fast-forward an allowed repository",
|
|
17996
|
-
description: "Fetch and fast-forward the checked-out branch of a cloned recipe repository; divergent history
|
|
18020
|
+
description: "Fetch and fast-forward the checked-out branch of a cloned recipe repository; divergent history, a dirty working tree, and anything needing a merge are rejected rather than forced. OMIT githubToken and Arbor pulls with its own managed recipe credential after rechecking the repository connection — the way a restored computer reaches current history. Supply githubToken instead to pull as the collaborator. Neither credential is stored or returned.",
|
|
17997
18021
|
inputSchema: {
|
|
17998
18022
|
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
17999
18023
|
repository: exports_external.string().describe("allowed owner/repository slug already cloned"),
|
|
18000
|
-
githubToken: exports_external.string().min(1).describe("short-lived GitHub token
|
|
18001
|
-
githubUsername: exports_external.string().optional().describe("GitHub username; defaults to x-access-token")
|
|
18024
|
+
githubToken: exports_external.string().min(1).optional().describe("short-lived collaborator GitHub token; omit to use Arbor's managed recipe credential"),
|
|
18025
|
+
githubUsername: exports_external.string().optional().describe("GitHub username for a supplied githubToken; defaults to x-access-token")
|
|
18002
18026
|
},
|
|
18003
18027
|
surfaces: ["computer-mcp"],
|
|
18004
18028
|
toolset: "loop",
|
|
@@ -18057,6 +18081,7 @@ var ACTION_DEFINITIONS = [
|
|
|
18057
18081
|
stateSchemaVersion: exports_external.number().int().min(0).optional().describe("durable schema this release writes; default 0"),
|
|
18058
18082
|
stateCompatibleFrom: exports_external.number().int().min(0).optional().describe("oldest durable schema this code can open"),
|
|
18059
18083
|
stateCompatibleThrough: exports_external.number().int().min(0).optional().describe("newest durable schema this code can open"),
|
|
18084
|
+
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"),
|
|
18060
18085
|
idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this one logical bundle publication")
|
|
18061
18086
|
},
|
|
18062
18087
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
@@ -19287,6 +19312,22 @@ var ACTION_DEFINITIONS = [
|
|
|
19287
19312
|
toolset: "apps",
|
|
19288
19313
|
run: forward("app.create")
|
|
19289
19314
|
},
|
|
19315
|
+
{
|
|
19316
|
+
name: "app_config_apply",
|
|
19317
|
+
title: "Apply App runtime config",
|
|
19318
|
+
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.",
|
|
19319
|
+
inputSchema: {
|
|
19320
|
+
appId: exports_external.string().describe("target App, app_…"),
|
|
19321
|
+
config: exports_external.record(exports_external.string(), exports_external.discriminatedUnion("kind", [
|
|
19322
|
+
exports_external.object({ kind: exports_external.literal("var"), value: exports_external.string().max(16384) }),
|
|
19323
|
+
exports_external.object({ kind: exports_external.literal("secret"), secretId: exports_external.string() })
|
|
19324
|
+
])).describe("complete desired runtime config object keyed by environment variable name"),
|
|
19325
|
+
dryRun: exports_external.boolean().optional().describe("validate and plan without mutating")
|
|
19326
|
+
},
|
|
19327
|
+
surfaces: ["mcp", "cli"],
|
|
19328
|
+
toolset: "apps",
|
|
19329
|
+
run: forward("app.config_apply")
|
|
19330
|
+
},
|
|
19290
19331
|
{
|
|
19291
19332
|
name: "app_deploy",
|
|
19292
19333
|
title: "Prepare an App deployment",
|
|
@@ -19842,6 +19883,9 @@ function kindOf(node) {
|
|
|
19842
19883
|
return "array";
|
|
19843
19884
|
case "boolean":
|
|
19844
19885
|
return "boolean";
|
|
19886
|
+
case "object":
|
|
19887
|
+
case "record":
|
|
19888
|
+
return "json";
|
|
19845
19889
|
default:
|
|
19846
19890
|
return "string";
|
|
19847
19891
|
}
|
|
@@ -19850,7 +19894,7 @@ function acceptedFlags(inputSchema) {
|
|
|
19850
19894
|
const out = new Set;
|
|
19851
19895
|
for (const spec of flagsForSchema(inputSchema)) {
|
|
19852
19896
|
out.add(spec.flag);
|
|
19853
|
-
if (spec.kind === "string")
|
|
19897
|
+
if (spec.kind === "string" || spec.kind === "json")
|
|
19854
19898
|
out.add(`${spec.flag}-file`);
|
|
19855
19899
|
}
|
|
19856
19900
|
return out;
|
|
@@ -19886,7 +19930,7 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19886
19930
|
const primary = primaryPositionalField(inputSchema);
|
|
19887
19931
|
const input = {};
|
|
19888
19932
|
for (const spec of flagsForSchema(inputSchema)) {
|
|
19889
|
-
if (spec.kind === "string") {
|
|
19933
|
+
if (spec.kind === "string" || spec.kind === "json") {
|
|
19890
19934
|
const fileSrc = lastValue(flags[`${spec.flag}-file`]);
|
|
19891
19935
|
if (fileSrc !== undefined) {
|
|
19892
19936
|
if (flags[spec.flag] !== undefined) {
|
|
@@ -19894,7 +19938,16 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19894
19938
|
}
|
|
19895
19939
|
if (fileSrc === true)
|
|
19896
19940
|
throw new UsageError(`--${spec.flag}-file expects a path (or - for stdin)`);
|
|
19897
|
-
|
|
19941
|
+
const sourced = readTextSource(String(fileSrc));
|
|
19942
|
+
if (spec.kind === "json") {
|
|
19943
|
+
try {
|
|
19944
|
+
input[spec.field] = JSON.parse(sourced);
|
|
19945
|
+
} catch {
|
|
19946
|
+
throw new UsageError(`--${spec.flag}-file must contain valid JSON`);
|
|
19947
|
+
}
|
|
19948
|
+
} else {
|
|
19949
|
+
input[spec.field] = sourced;
|
|
19950
|
+
}
|
|
19898
19951
|
continue;
|
|
19899
19952
|
}
|
|
19900
19953
|
}
|
|
@@ -19958,6 +20011,14 @@ function buildInput(inputSchema, flags, command) {
|
|
|
19958
20011
|
input[spec.field] = out;
|
|
19959
20012
|
break;
|
|
19960
20013
|
}
|
|
20014
|
+
case "json": {
|
|
20015
|
+
try {
|
|
20016
|
+
input[spec.field] = JSON.parse(String(lastValue(raw)));
|
|
20017
|
+
} catch {
|
|
20018
|
+
throw new UsageError(`--${spec.flag} must be valid JSON`);
|
|
20019
|
+
}
|
|
20020
|
+
break;
|
|
20021
|
+
}
|
|
19961
20022
|
case "boolean": {
|
|
19962
20023
|
const v = lastValue(raw);
|
|
19963
20024
|
input[spec.field] = v === true ? true : v !== "false";
|
package/package.json
CHANGED