@agent-native/dispatch 0.15.20 → 0.15.21
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/actions/provider-api-catalog.d.ts +1 -0
- package/dist/actions/provider-api-register.d.ts +14 -14
- package/dist/actions/remix-workspace-template.d.ts +20 -32
- package/dist/actions/set-app-creation-settings.js +2 -2
- package/dist/actions/set-app-creation-settings.js.map +1 -1
- package/dist/actions/start-workspace-app-creation.d.ts +1 -45
- package/dist/components/create-app-popover.d.ts.map +1 -1
- package/dist/components/create-app-popover.js +30 -2
- package/dist/components/create-app-popover.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +1 -1
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/workspace-template-card.d.ts.map +1 -1
- package/dist/components/workspace-template-card.js +14 -1
- package/dist/components/workspace-template-card.js.map +1 -1
- package/dist/server/lib/app-creation-store.d.ts +36 -37
- package/dist/server/lib/app-creation-store.d.ts.map +1 -1
- package/dist/server/lib/app-creation-store.js +71 -6
- package/dist/server/lib/app-creation-store.js.map +1 -1
- package/dist/server/lib/provider-api.d.ts +1 -0
- package/dist/server/lib/provider-api.d.ts.map +1 -1
- package/dist/server/plugins/integrations.js +1 -1
- package/dist/server/plugins/integrations.js.map +1 -1
- package/package.json +2 -2
- package/src/actions/set-app-creation-settings.ts +4 -2
- package/src/components/create-app-popover.spec.tsx +249 -0
- package/src/components/create-app-popover.tsx +77 -10
- package/src/components/layout/Layout.tsx +9 -6
- package/src/components/workspace-template-card.tsx +11 -1
- package/src/server/lib/app-creation-store.spec.ts +252 -0
- package/src/server/lib/app-creation-store.ts +148 -8
- package/src/server/plugins/integrations.ts +1 -1
|
@@ -3,7 +3,8 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { getDbExec } from "@agent-native/core/db";
|
|
6
|
-
import {
|
|
6
|
+
import { deleteAppSecret, writeAppSecret, } from "@agent-native/core/secrets";
|
|
7
|
+
import { getBuilderBranchProjectId, getRequestContext, isIntegrationCallerRequest, resolveBuilderBranchProjectId, resolveBuilderCredentialsDetailed, runBuilderAgent, } from "@agent-native/core/server";
|
|
7
8
|
import { getSetting, putSetting } from "@agent-native/core/settings";
|
|
8
9
|
import { assertValidWorkspaceAppId } from "@agent-native/core/shared";
|
|
9
10
|
import { identityKeyForIncoming } from "./dispatch-integrations.js";
|
|
@@ -11,6 +12,8 @@ import { currentOrgId, currentOwnerEmail, recordAudit, resolveLinkedOwner, } fro
|
|
|
11
12
|
import { createRequest, listSecrets } from "./vault-store.js";
|
|
12
13
|
import { grantWorkspaceResourcesToApp, listWorkspaceResourceOptions, } from "./workspace-resources-store.js";
|
|
13
14
|
const SETTINGS_KEY = "dispatch-app-creation-settings";
|
|
15
|
+
const BUILDER_BRANCH_PROJECT_SECRET_KEY = "BUILDER_BRANCH_PROJECT_ID";
|
|
16
|
+
const BUILDER_BRANCH_PROJECT_SECRET_DESCRIPTION = "Builder project for cloud code-change branches (set in Dispatch)";
|
|
14
17
|
const WORKSPACE_APP_METADATA_SETTINGS_KEY = "workspace-app-metadata";
|
|
15
18
|
const WORKSPACE_APPS_ENV_KEY = "AGENT_NATIVE_WORKSPACE_APPS_JSON";
|
|
16
19
|
const WORKSPACE_APPS_MANIFEST_FILE = "workspace-apps.json";
|
|
@@ -83,6 +86,13 @@ function scopedSettingsKey() {
|
|
|
83
86
|
return `${SETTINGS_KEY}:org:${orgId}`;
|
|
84
87
|
return `${SETTINGS_KEY}:user:${currentOwnerEmail()}`;
|
|
85
88
|
}
|
|
89
|
+
function builderProjectSecretTarget() {
|
|
90
|
+
const orgId = currentOrgId();
|
|
91
|
+
if (orgId)
|
|
92
|
+
return { scope: "org", scopeId: orgId };
|
|
93
|
+
const email = currentOwnerEmail();
|
|
94
|
+
return email ? { scope: "workspace", scopeId: `solo:${email}` } : null;
|
|
95
|
+
}
|
|
86
96
|
function workspaceAppMetadataSettingsKey() {
|
|
87
97
|
const orgId = currentOrgId();
|
|
88
98
|
if (orgId)
|
|
@@ -1158,6 +1168,28 @@ export async function setAppCreationSettings(input) {
|
|
|
1158
1168
|
await assertCanManageAppCreationSettings();
|
|
1159
1169
|
const builderProjectId = input.builderProjectId?.trim() || null;
|
|
1160
1170
|
const raw = await readSettingsRecord();
|
|
1171
|
+
// The credential store, not this settings row, is what
|
|
1172
|
+
// `resolveBuilderBranchProjectId()` reads. Write it first: a saved setting
|
|
1173
|
+
// whose secret never landed reports the project as configured while cloud
|
|
1174
|
+
// code changes stay silently disabled.
|
|
1175
|
+
const secretTarget = builderProjectSecretTarget();
|
|
1176
|
+
if (secretTarget) {
|
|
1177
|
+
const ref = {
|
|
1178
|
+
key: BUILDER_BRANCH_PROJECT_SECRET_KEY,
|
|
1179
|
+
scope: secretTarget.scope,
|
|
1180
|
+
scopeId: secretTarget.scopeId,
|
|
1181
|
+
};
|
|
1182
|
+
if (builderProjectId) {
|
|
1183
|
+
await writeAppSecret({
|
|
1184
|
+
...ref,
|
|
1185
|
+
value: builderProjectId,
|
|
1186
|
+
description: BUILDER_BRANCH_PROJECT_SECRET_DESCRIPTION,
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
else {
|
|
1190
|
+
await deleteAppSecret(ref);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1161
1193
|
await putSetting(scopedSettingsKey(), { ...raw, builderProjectId });
|
|
1162
1194
|
await recordAudit({
|
|
1163
1195
|
action: "settings.updated",
|
|
@@ -1292,6 +1324,7 @@ async function remoteAppCreationAuthorization() {
|
|
|
1292
1324
|
return { ok: true };
|
|
1293
1325
|
return {
|
|
1294
1326
|
ok: false,
|
|
1327
|
+
reason: "identity-not-linked",
|
|
1295
1328
|
message: "Messaging-triggered app creation is using the deployment default Dispatch owner. " +
|
|
1296
1329
|
"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.",
|
|
1297
1330
|
};
|
|
@@ -1303,6 +1336,7 @@ async function remoteAppCreationAuthorization() {
|
|
|
1303
1336
|
: "Synthetic integration";
|
|
1304
1337
|
return {
|
|
1305
1338
|
ok: false,
|
|
1339
|
+
reason: "identity-not-linked",
|
|
1306
1340
|
message: `${source} app creation needs a trusted Dispatch owner before Builder can start a branch. ` +
|
|
1307
1341
|
"Link the messaging identity to a Dispatch user with /link, start the app from Dispatch while signed in, or explicitly set ENABLE_BUILDER=true for this deployment.",
|
|
1308
1342
|
};
|
|
@@ -1405,6 +1439,7 @@ export async function startWorkspaceAppCreation(input) {
|
|
|
1405
1439
|
return {
|
|
1406
1440
|
mode: "builder-unavailable",
|
|
1407
1441
|
appId: initial.appId,
|
|
1442
|
+
reason: authorization.reason,
|
|
1408
1443
|
message: authorization.message,
|
|
1409
1444
|
};
|
|
1410
1445
|
}
|
|
@@ -1450,10 +1485,40 @@ export async function startWorkspaceAppCreation(input) {
|
|
|
1450
1485
|
message: "This requires a code change. Edit locally or use Builder.io to edit this code in the cloud and continue customizing the app any way you like.",
|
|
1451
1486
|
};
|
|
1452
1487
|
}
|
|
1488
|
+
let builderCreds;
|
|
1489
|
+
try {
|
|
1490
|
+
builderCreds = await resolveBuilderCredentialsDetailed();
|
|
1491
|
+
}
|
|
1492
|
+
catch {
|
|
1493
|
+
return {
|
|
1494
|
+
mode: "builder-unavailable",
|
|
1495
|
+
appId: built.appId,
|
|
1496
|
+
reason: "credential-store-unavailable",
|
|
1497
|
+
projectId: settings.builderProjectId,
|
|
1498
|
+
message: "Could not read your Builder connection just now. Try creating the app again in a moment.",
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
if (builderCreds.lookupFailed) {
|
|
1502
|
+
return {
|
|
1503
|
+
mode: "builder-unavailable",
|
|
1504
|
+
appId: built.appId,
|
|
1505
|
+
reason: "credential-store-unavailable",
|
|
1506
|
+
projectId: settings.builderProjectId,
|
|
1507
|
+
message: "Could not read your Builder connection just now. Try creating the app again in a moment.",
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
if (!builderCreds.privateKey || !builderCreds.publicKey) {
|
|
1511
|
+
return {
|
|
1512
|
+
mode: "builder-unavailable",
|
|
1513
|
+
appId: built.appId,
|
|
1514
|
+
reason: "builder-not-connected",
|
|
1515
|
+
projectId: settings.builderProjectId,
|
|
1516
|
+
message: "Connect your Builder account to create apps from Dispatch.",
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
const builderUserId = builderCreds.userId || undefined;
|
|
1453
1520
|
let result;
|
|
1454
1521
|
try {
|
|
1455
|
-
const builderCreds = await resolveBuilderCredentials().catch(() => null);
|
|
1456
|
-
const builderUserId = builderCreds?.userId || undefined;
|
|
1457
1522
|
result = normalizeBuilderRunResult(await runBuilderAgent({
|
|
1458
1523
|
prompt,
|
|
1459
1524
|
projectId: settings.builderProjectId,
|
|
@@ -1469,10 +1534,10 @@ export async function startWorkspaceAppCreation(input) {
|
|
|
1469
1534
|
return {
|
|
1470
1535
|
mode: "builder-unavailable",
|
|
1471
1536
|
appId: built.appId,
|
|
1537
|
+
reason: "builder-error",
|
|
1472
1538
|
projectId: settings.builderProjectId,
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
`link the messaging identity to that user, or configure deployment-managed Builder credentials for this workspace.`,
|
|
1539
|
+
detail,
|
|
1540
|
+
message: "Builder could not start the app branch. This is usually temporary — try again.",
|
|
1476
1541
|
};
|
|
1477
1542
|
}
|
|
1478
1543
|
await recordPendingWorkspaceApp({
|