@agent-native/dispatch 0.40.42 → 0.40.43-nightly-20261029092708

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @agent-native/dispatch
2
2
 
3
+ ## 0.40.43-nightly-20261029092708
4
+
5
+ ### Patch Changes
6
+
7
+ - 25daf38: Expose bounded stage codes when Builder branch readback cannot be verified.
8
+ - Updated dependencies [86af196]
9
+ - Updated dependencies [c96a41d]
10
+ - Updated dependencies [b6a2ddc]
11
+ - Updated dependencies [b6a2ddc]
12
+ - Updated dependencies [25daf38]
13
+ - @agent-native/core@0.222.1-nightly-20261029092708
14
+ - @agent-native/toolkit@0.222.1-nightly-20261029092708
15
+
3
16
  ## 0.40.42
4
17
 
5
18
  ### Patch Changes
@@ -48,9 +48,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
48
48
  scope?: "org" | "user" | undefined;
49
49
  }, {
50
50
  id?: undefined;
51
+ provider?: undefined;
51
52
  deleted?: undefined;
52
53
  message?: undefined;
53
- found?: undefined;
54
54
  providers: {
55
55
  id: string;
56
56
  label: string;
@@ -61,7 +61,7 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
61
61
  updatedAt: number;
62
62
  }[];
63
63
  count: number;
64
- provider?: undefined;
64
+ found?: undefined;
65
65
  registered?: undefined;
66
66
  label?: undefined;
67
67
  } | {
@@ -75,31 +75,31 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
75
75
  registered?: undefined;
76
76
  label?: undefined;
77
77
  } | {
78
+ provider?: undefined;
78
79
  count?: undefined;
79
80
  deleted?: undefined;
80
81
  message?: undefined;
81
82
  providers?: undefined;
82
- provider?: undefined;
83
83
  found: boolean;
84
84
  id: string;
85
85
  registered?: undefined;
86
86
  label?: undefined;
87
87
  } | {
88
+ provider?: undefined;
88
89
  count?: undefined;
89
90
  message?: undefined;
90
- found?: undefined;
91
91
  providers?: undefined;
92
- provider?: undefined;
92
+ found?: undefined;
93
93
  deleted: boolean;
94
94
  id: string;
95
95
  registered?: undefined;
96
96
  label?: undefined;
97
97
  } | {
98
+ provider?: undefined;
98
99
  count?: undefined;
99
100
  deleted?: undefined;
100
- found?: undefined;
101
101
  providers?: undefined;
102
- provider?: undefined;
102
+ found?: undefined;
103
103
  registered: boolean;
104
104
  id: string;
105
105
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"community-install-verification.d.ts","sourceRoot":"","sources":["../../../src/server/lib/community-install-verification.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,kCAAkC,itBAgB9C,CAAC;AA+JF,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,wFA8FA"}
1
+ {"version":3,"file":"community-install-verification.d.ts","sourceRoot":"","sources":["../../../src/server/lib/community-install-verification.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,kCAAkC,itBAgB9C,CAAC;AAkMF,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,wFA8FA"}
@@ -11,6 +11,35 @@ export const communityInstallVerificationErrors = defineActionErrors("community_
11
11
  function verificationFail(message, code, options) {
12
12
  return communityInstallVerificationErrors.fail(message, code, options);
13
13
  }
14
+ const READBACK_STAGES = new Set([
15
+ "status_request",
16
+ "status_shape",
17
+ "status_binding",
18
+ "status_currentness",
19
+ "post_read_status_request",
20
+ "post_read_status_shape",
21
+ "post_read_status_binding",
22
+ "post_read_status_currentness",
23
+ "download_url_request",
24
+ "download_url_shape",
25
+ "download_url_binding",
26
+ "bundle_download",
27
+ "bundle_read",
28
+ "bundle_digest",
29
+ "bundle_parse",
30
+ "target_subtree_missing",
31
+ "post_read_currentness",
32
+ "app_integrity",
33
+ "snapshot_ref",
34
+ ]);
35
+ function readbackStage(error) {
36
+ const stage = error && typeof error === "object"
37
+ ? error.readbackStage
38
+ : undefined;
39
+ return typeof stage === "string" && READBACK_STAGES.has(stage)
40
+ ? stage
41
+ : "unknown";
42
+ }
14
43
  function requireHumanOrgOwner() {
15
44
  const context = getRequestContext();
16
45
  const orgId = currentOrgId();
@@ -87,13 +116,16 @@ function failBranchReadback(error) {
87
116
  verificationFail("Builder project read access is missing or does not include this project.", "community_verification_readback_forbidden", { statusCode: error.code === "forbidden" ? 403 : 409 });
88
117
  }
89
118
  if (error.code === "unverified" || error.code === "integrity_failed") {
90
- verificationFail("Builder could not provide a complete, identity-bound branch snapshot.", "community_verification_readback_unverified", { statusCode: 422 });
119
+ verificationFail("Builder could not provide a complete, identity-bound branch snapshot.", "community_verification_readback_unverified", { statusCode: 422, details: { readbackStage: readbackStage(error) } });
91
120
  }
92
121
  if (error.code === "invalid_request") {
93
122
  verificationFail("Builder rejected the requested branch reference.", "community_verification_branch_invalid", { statusCode: 400 });
94
123
  }
95
124
  }
96
- verificationFail("Builder branch readback is unavailable. Try again later.", "community_verification_readback_unavailable", { statusCode: 503 });
125
+ verificationFail("Builder branch readback is unavailable. Try again later.", "community_verification_readback_unavailable", {
126
+ statusCode: 503,
127
+ details: { readbackStage: readbackStage(error) },
128
+ });
97
129
  }
98
130
  export async function verifyCuratedCommunityApp(input) {
99
131
  const { orgId, ownerEmail } = requireHumanOrgOwner();
@@ -142,10 +174,10 @@ export async function verifyCuratedCommunityApp(input) {
142
174
  case "file_too_large":
143
175
  case "total_too_large":
144
176
  case "blob_mismatch":
145
- verificationFail("Builder branch files do not match the reviewed community template.", "community_verification_integrity_failed", { statusCode: 422 });
177
+ verificationFail("Builder branch files do not match the reviewed community template.", "community_verification_integrity_failed", { statusCode: 422, details: { readbackStage: "app_integrity" } });
146
178
  case "ref_mismatch":
147
179
  case "invalid_snapshot":
148
- verificationFail("Builder could not provide a complete, identity-bound branch snapshot.", "community_verification_readback_unverified", { statusCode: 422 });
180
+ verificationFail("Builder could not provide a complete, identity-bound branch snapshot.", "community_verification_readback_unverified", { statusCode: 422, details: { readbackStage: "snapshot_ref" } });
149
181
  case "invalid_source":
150
182
  verificationFail("The reviewed community catalog entry is invalid.", "community_verification_catalog_invalid", { statusCode: 500 });
151
183
  case "invalid_target":
@@ -1 +1 @@
1
- {"version":3,"file":"community-install-verification.js","sourceRoot":"","sources":["../../../src/server/lib/community-install-verification.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineActionErrors } from \"@agent-native/core/action\";\nimport {\n BuilderBranchFilesError,\n getRequestContext,\n readBuilderBranchFiles,\n readOrgMemberRole,\n} from \"@agent-native/core/server\";\nimport {\n getWorkspaceAppIdValidationError,\n normalizeWorkspaceAppId,\n} from \"@agent-native/core/shared\";\nimport {\n BUILTIN_AGENT_CATALOG_IDS,\n HIDDEN_FIRST_PARTY_AGENT_IDS,\n} from \"@agent-native/core/shared/first-party-agents\";\n\nimport { getAppCreationSettings } from \"./app-creation-store.js\";\nimport { CURATED_COMMUNITY_APP_SOURCES } from \"./community-apps.js\";\nimport {\n CommunityInstallIntegrityError,\n verifyCommunityBranchFiles,\n} from \"./community-install-integrity.js\";\nimport { CURATED_WORKSPACE_TEMPLATES } from \"./curated-workspace-templates.js\";\nimport { currentOrgId, currentOwnerEmail } from \"./dispatch-store.js\";\n\nexport const communityInstallVerificationErrors = defineActionErrors(\n \"community_verification_identity_required\",\n \"community_verification_role_unavailable\",\n \"community_verification_owner_required\",\n \"community_verification_source_unknown\",\n \"community_verification_app_id_invalid\",\n \"community_verification_app_id_shadows_first_party\",\n \"community_verification_branch_invalid\",\n \"community_verification_project_required\",\n \"community_verification_project_unavailable\",\n \"community_verification_readback_unavailable\",\n \"community_verification_readback_forbidden\",\n \"community_verification_readback_unverified\",\n \"community_verification_integrity_failed\",\n \"community_verification_catalog_invalid\",\n \"community_verification_internal_error\",\n);\n\nfunction verificationFail(\n message: string,\n code: Parameters<typeof communityInstallVerificationErrors.fail>[1],\n options: { statusCode: number },\n): never {\n return communityInstallVerificationErrors.fail(message, code, options);\n}\n\nfunction requireHumanOrgOwner(): { orgId: string; ownerEmail: string } {\n const context = getRequestContext();\n const orgId = currentOrgId();\n const contextEmail = context?.userEmail?.trim().toLowerCase();\n if (\n !context ||\n !context.authUserId?.trim() ||\n !contextEmail ||\n !orgId ||\n context.orgId !== orgId ||\n context.isSyntheticTraffic === true ||\n context.isIntegrationCaller === true ||\n context.integration !== undefined ||\n context.verifiedServiceIdentity !== undefined ||\n context.a2aIdentityAssurance !== undefined ||\n context.agentRunAnonymous === true ||\n context.authCapability !== undefined ||\n typeof context.identityAuthenticatedAtMs !== \"number\" ||\n !Number.isFinite(context.identityAuthenticatedAtMs) ||\n context.orgScope === \"personal\" ||\n /^integration@|@integration\\.local$/i.test(contextEmail)\n ) {\n verificationFail(\n \"Sign in directly to an organization as an owner or admin to verify a Builder community branch.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n\n let ownerEmail: string;\n try {\n ownerEmail = currentOwnerEmail().trim().toLowerCase();\n } catch {\n verificationFail(\n \"An authenticated organization owner or admin is required.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n if (!ownerEmail || ownerEmail !== contextEmail) {\n verificationFail(\n \"An authenticated organization owner or admin is required.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n\n return { orgId, ownerEmail };\n}\n\nasync function requireOrganizationOwnerOrAdmin(\n orgId: string,\n ownerEmail: string,\n): Promise<void> {\n let role: string | null;\n try {\n role = await readOrgMemberRole(orgId, ownerEmail);\n } catch {\n verificationFail(\n \"Organization membership could not be verified. Try again shortly.\",\n \"community_verification_role_unavailable\",\n { statusCode: 503 },\n );\n }\n if (role !== \"owner\" && role !== \"admin\") {\n verificationFail(\n \"Only organization owners and admins can verify Builder community branches.\",\n \"community_verification_owner_required\",\n { statusCode: 403 },\n );\n }\n}\n\nfunction requireAppId(appIdInput: string): string {\n const appId = normalizeWorkspaceAppId(appIdInput);\n if (!appId || appId.length > 64 || getWorkspaceAppIdValidationError(appId)) {\n verificationFail(\n \"Choose a valid, non-reserved workspace app id.\",\n \"community_verification_app_id_invalid\",\n { statusCode: 400 },\n );\n }\n if (\n CURATED_WORKSPACE_TEMPLATES.some((template) => template.id === appId) ||\n BUILTIN_AGENT_CATALOG_IDS.includes(appId) ||\n HIDDEN_FIRST_PARTY_AGENT_IDS.has(appId)\n ) {\n verificationFail(\n \"Community apps cannot use a first-party template app id.\",\n \"community_verification_app_id_shadows_first_party\",\n { statusCode: 409 },\n );\n }\n return appId;\n}\n\nfunction requireBranchName(branchNameInput: string): string {\n const branchName = branchNameInput.trim();\n if (\n branchName !== branchNameInput ||\n branchName.length > 256 ||\n !branchName ||\n branchName\n .split(\"/\")\n .some(\n (part) =>\n !/^[A-Za-z0-9_.-]+$/.test(part) || part === \".\" || part === \"..\",\n )\n ) {\n verificationFail(\n \"Choose a valid Builder branch name.\",\n \"community_verification_branch_invalid\",\n { statusCode: 400 },\n );\n }\n return branchName;\n}\n\nfunction failBranchReadback(error: unknown): never {\n if (error instanceof BuilderBranchFilesError) {\n if (error.code === \"forbidden\" || error.code === \"not_connected\") {\n verificationFail(\n \"Builder project read access is missing or does not include this project.\",\n \"community_verification_readback_forbidden\",\n { statusCode: error.code === \"forbidden\" ? 403 : 409 },\n );\n }\n if (error.code === \"unverified\" || error.code === \"integrity_failed\") {\n verificationFail(\n \"Builder could not provide a complete, identity-bound branch snapshot.\",\n \"community_verification_readback_unverified\",\n { statusCode: 422 },\n );\n }\n if (error.code === \"invalid_request\") {\n verificationFail(\n \"Builder rejected the requested branch reference.\",\n \"community_verification_branch_invalid\",\n { statusCode: 400 },\n );\n }\n }\n verificationFail(\n \"Builder branch readback is unavailable. Try again later.\",\n \"community_verification_readback_unavailable\",\n { statusCode: 503 },\n );\n}\n\nexport async function verifyCuratedCommunityApp(input: {\n sourceId: string;\n appId: string;\n branchName: string;\n}) {\n const { orgId, ownerEmail } = requireHumanOrgOwner();\n await requireOrganizationOwnerOrAdmin(orgId, ownerEmail);\n\n const source = CURATED_COMMUNITY_APP_SOURCES.find(\n (candidate) => candidate.id === input.sourceId.trim(),\n );\n if (!source) {\n verificationFail(\n \"That community app is not in Dispatch's reviewed install catalog.\",\n \"community_verification_source_unknown\",\n { statusCode: 404 },\n );\n }\n\n const appId = requireAppId(input.appId);\n const branchName = requireBranchName(input.branchName);\n\n let settings: Awaited<ReturnType<typeof getAppCreationSettings>>;\n try {\n settings = await getAppCreationSettings();\n } catch {\n verificationFail(\n \"The organization Builder project setting could not be read. Try again later.\",\n \"community_verification_project_unavailable\",\n { statusCode: 503 },\n );\n }\n const projectId = settings.savedBuilderProjectId?.trim();\n if (!projectId || settings.builderProjectId !== projectId) {\n verificationFail(\n \"Configure a Builder project for this organization before verifying a branch.\",\n \"community_verification_project_required\",\n { statusCode: 409 },\n );\n }\n\n let snapshot: Awaited<ReturnType<typeof readBuilderBranchFiles>>;\n try {\n snapshot = await readBuilderBranchFiles({\n projectId,\n branchName,\n appPath: `apps/${appId}`,\n });\n } catch (error) {\n failBranchReadback(error);\n }\n\n try {\n return verifyCommunityBranchFiles(source, appId, snapshot, {\n projectId,\n branchName,\n });\n } catch (error) {\n if (!(error instanceof CommunityInstallIntegrityError)) {\n verificationFail(\n \"Community branch verification could not be completed.\",\n \"community_verification_internal_error\",\n { statusCode: 500 },\n );\n }\n\n switch (error.code) {\n case \"file_set_mismatch\":\n case \"file_mode_unsupported\":\n case \"file_too_large\":\n case \"total_too_large\":\n case \"blob_mismatch\":\n verificationFail(\n \"Builder branch files do not match the reviewed community template.\",\n \"community_verification_integrity_failed\",\n { statusCode: 422 },\n );\n case \"ref_mismatch\":\n case \"invalid_snapshot\":\n verificationFail(\n \"Builder could not provide a complete, identity-bound branch snapshot.\",\n \"community_verification_readback_unverified\",\n { statusCode: 422 },\n );\n case \"invalid_source\":\n verificationFail(\n \"The reviewed community catalog entry is invalid.\",\n \"community_verification_catalog_invalid\",\n { statusCode: 500 },\n );\n case \"invalid_target\":\n verificationFail(\n \"Community branch verification could not be completed.\",\n \"community_verification_internal_error\",\n { statusCode: 500 },\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"community-install-verification.js","sourceRoot":"","sources":["../../../src/server/lib/community-install-verification.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineActionErrors } from \"@agent-native/core/action\";\nimport {\n BuilderBranchFilesError,\n getRequestContext,\n readBuilderBranchFiles,\n readOrgMemberRole,\n} from \"@agent-native/core/server\";\nimport {\n getWorkspaceAppIdValidationError,\n normalizeWorkspaceAppId,\n} from \"@agent-native/core/shared\";\nimport {\n BUILTIN_AGENT_CATALOG_IDS,\n HIDDEN_FIRST_PARTY_AGENT_IDS,\n} from \"@agent-native/core/shared/first-party-agents\";\n\nimport { getAppCreationSettings } from \"./app-creation-store.js\";\nimport { CURATED_COMMUNITY_APP_SOURCES } from \"./community-apps.js\";\nimport {\n CommunityInstallIntegrityError,\n verifyCommunityBranchFiles,\n} from \"./community-install-integrity.js\";\nimport { CURATED_WORKSPACE_TEMPLATES } from \"./curated-workspace-templates.js\";\nimport { currentOrgId, currentOwnerEmail } from \"./dispatch-store.js\";\n\nexport const communityInstallVerificationErrors = defineActionErrors(\n \"community_verification_identity_required\",\n \"community_verification_role_unavailable\",\n \"community_verification_owner_required\",\n \"community_verification_source_unknown\",\n \"community_verification_app_id_invalid\",\n \"community_verification_app_id_shadows_first_party\",\n \"community_verification_branch_invalid\",\n \"community_verification_project_required\",\n \"community_verification_project_unavailable\",\n \"community_verification_readback_unavailable\",\n \"community_verification_readback_forbidden\",\n \"community_verification_readback_unverified\",\n \"community_verification_integrity_failed\",\n \"community_verification_catalog_invalid\",\n \"community_verification_internal_error\",\n);\n\nfunction verificationFail(\n message: string,\n code: Parameters<typeof communityInstallVerificationErrors.fail>[1],\n options: { statusCode: number; details?: Record<string, unknown> },\n): never {\n return communityInstallVerificationErrors.fail(message, code, options);\n}\n\nconst READBACK_STAGES = new Set([\n \"status_request\",\n \"status_shape\",\n \"status_binding\",\n \"status_currentness\",\n \"post_read_status_request\",\n \"post_read_status_shape\",\n \"post_read_status_binding\",\n \"post_read_status_currentness\",\n \"download_url_request\",\n \"download_url_shape\",\n \"download_url_binding\",\n \"bundle_download\",\n \"bundle_read\",\n \"bundle_digest\",\n \"bundle_parse\",\n \"target_subtree_missing\",\n \"post_read_currentness\",\n \"app_integrity\",\n \"snapshot_ref\",\n]);\n\nfunction readbackStage(error: unknown): string {\n const stage =\n error && typeof error === \"object\"\n ? (error as { readbackStage?: unknown }).readbackStage\n : undefined;\n return typeof stage === \"string\" && READBACK_STAGES.has(stage)\n ? stage\n : \"unknown\";\n}\n\nfunction requireHumanOrgOwner(): { orgId: string; ownerEmail: string } {\n const context = getRequestContext();\n const orgId = currentOrgId();\n const contextEmail = context?.userEmail?.trim().toLowerCase();\n if (\n !context ||\n !context.authUserId?.trim() ||\n !contextEmail ||\n !orgId ||\n context.orgId !== orgId ||\n context.isSyntheticTraffic === true ||\n context.isIntegrationCaller === true ||\n context.integration !== undefined ||\n context.verifiedServiceIdentity !== undefined ||\n context.a2aIdentityAssurance !== undefined ||\n context.agentRunAnonymous === true ||\n context.authCapability !== undefined ||\n typeof context.identityAuthenticatedAtMs !== \"number\" ||\n !Number.isFinite(context.identityAuthenticatedAtMs) ||\n context.orgScope === \"personal\" ||\n /^integration@|@integration\\.local$/i.test(contextEmail)\n ) {\n verificationFail(\n \"Sign in directly to an organization as an owner or admin to verify a Builder community branch.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n\n let ownerEmail: string;\n try {\n ownerEmail = currentOwnerEmail().trim().toLowerCase();\n } catch {\n verificationFail(\n \"An authenticated organization owner or admin is required.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n if (!ownerEmail || ownerEmail !== contextEmail) {\n verificationFail(\n \"An authenticated organization owner or admin is required.\",\n \"community_verification_identity_required\",\n { statusCode: 403 },\n );\n }\n\n return { orgId, ownerEmail };\n}\n\nasync function requireOrganizationOwnerOrAdmin(\n orgId: string,\n ownerEmail: string,\n): Promise<void> {\n let role: string | null;\n try {\n role = await readOrgMemberRole(orgId, ownerEmail);\n } catch {\n verificationFail(\n \"Organization membership could not be verified. Try again shortly.\",\n \"community_verification_role_unavailable\",\n { statusCode: 503 },\n );\n }\n if (role !== \"owner\" && role !== \"admin\") {\n verificationFail(\n \"Only organization owners and admins can verify Builder community branches.\",\n \"community_verification_owner_required\",\n { statusCode: 403 },\n );\n }\n}\n\nfunction requireAppId(appIdInput: string): string {\n const appId = normalizeWorkspaceAppId(appIdInput);\n if (!appId || appId.length > 64 || getWorkspaceAppIdValidationError(appId)) {\n verificationFail(\n \"Choose a valid, non-reserved workspace app id.\",\n \"community_verification_app_id_invalid\",\n { statusCode: 400 },\n );\n }\n if (\n CURATED_WORKSPACE_TEMPLATES.some((template) => template.id === appId) ||\n BUILTIN_AGENT_CATALOG_IDS.includes(appId) ||\n HIDDEN_FIRST_PARTY_AGENT_IDS.has(appId)\n ) {\n verificationFail(\n \"Community apps cannot use a first-party template app id.\",\n \"community_verification_app_id_shadows_first_party\",\n { statusCode: 409 },\n );\n }\n return appId;\n}\n\nfunction requireBranchName(branchNameInput: string): string {\n const branchName = branchNameInput.trim();\n if (\n branchName !== branchNameInput ||\n branchName.length > 256 ||\n !branchName ||\n branchName\n .split(\"/\")\n .some(\n (part) =>\n !/^[A-Za-z0-9_.-]+$/.test(part) || part === \".\" || part === \"..\",\n )\n ) {\n verificationFail(\n \"Choose a valid Builder branch name.\",\n \"community_verification_branch_invalid\",\n { statusCode: 400 },\n );\n }\n return branchName;\n}\n\nfunction failBranchReadback(error: unknown): never {\n if (error instanceof BuilderBranchFilesError) {\n if (error.code === \"forbidden\" || error.code === \"not_connected\") {\n verificationFail(\n \"Builder project read access is missing or does not include this project.\",\n \"community_verification_readback_forbidden\",\n { statusCode: error.code === \"forbidden\" ? 403 : 409 },\n );\n }\n if (error.code === \"unverified\" || error.code === \"integrity_failed\") {\n verificationFail(\n \"Builder could not provide a complete, identity-bound branch snapshot.\",\n \"community_verification_readback_unverified\",\n { statusCode: 422, details: { readbackStage: readbackStage(error) } },\n );\n }\n if (error.code === \"invalid_request\") {\n verificationFail(\n \"Builder rejected the requested branch reference.\",\n \"community_verification_branch_invalid\",\n { statusCode: 400 },\n );\n }\n }\n verificationFail(\n \"Builder branch readback is unavailable. Try again later.\",\n \"community_verification_readback_unavailable\",\n {\n statusCode: 503,\n details: { readbackStage: readbackStage(error) },\n },\n );\n}\n\nexport async function verifyCuratedCommunityApp(input: {\n sourceId: string;\n appId: string;\n branchName: string;\n}) {\n const { orgId, ownerEmail } = requireHumanOrgOwner();\n await requireOrganizationOwnerOrAdmin(orgId, ownerEmail);\n\n const source = CURATED_COMMUNITY_APP_SOURCES.find(\n (candidate) => candidate.id === input.sourceId.trim(),\n );\n if (!source) {\n verificationFail(\n \"That community app is not in Dispatch's reviewed install catalog.\",\n \"community_verification_source_unknown\",\n { statusCode: 404 },\n );\n }\n\n const appId = requireAppId(input.appId);\n const branchName = requireBranchName(input.branchName);\n\n let settings: Awaited<ReturnType<typeof getAppCreationSettings>>;\n try {\n settings = await getAppCreationSettings();\n } catch {\n verificationFail(\n \"The organization Builder project setting could not be read. Try again later.\",\n \"community_verification_project_unavailable\",\n { statusCode: 503 },\n );\n }\n const projectId = settings.savedBuilderProjectId?.trim();\n if (!projectId || settings.builderProjectId !== projectId) {\n verificationFail(\n \"Configure a Builder project for this organization before verifying a branch.\",\n \"community_verification_project_required\",\n { statusCode: 409 },\n );\n }\n\n let snapshot: Awaited<ReturnType<typeof readBuilderBranchFiles>>;\n try {\n snapshot = await readBuilderBranchFiles({\n projectId,\n branchName,\n appPath: `apps/${appId}`,\n });\n } catch (error) {\n failBranchReadback(error);\n }\n\n try {\n return verifyCommunityBranchFiles(source, appId, snapshot, {\n projectId,\n branchName,\n });\n } catch (error) {\n if (!(error instanceof CommunityInstallIntegrityError)) {\n verificationFail(\n \"Community branch verification could not be completed.\",\n \"community_verification_internal_error\",\n { statusCode: 500 },\n );\n }\n\n switch (error.code) {\n case \"file_set_mismatch\":\n case \"file_mode_unsupported\":\n case \"file_too_large\":\n case \"total_too_large\":\n case \"blob_mismatch\":\n verificationFail(\n \"Builder branch files do not match the reviewed community template.\",\n \"community_verification_integrity_failed\",\n { statusCode: 422, details: { readbackStage: \"app_integrity\" } },\n );\n case \"ref_mismatch\":\n case \"invalid_snapshot\":\n verificationFail(\n \"Builder could not provide a complete, identity-bound branch snapshot.\",\n \"community_verification_readback_unverified\",\n { statusCode: 422, details: { readbackStage: \"snapshot_ref\" } },\n );\n case \"invalid_source\":\n verificationFail(\n \"The reviewed community catalog entry is invalid.\",\n \"community_verification_catalog_invalid\",\n { statusCode: 500 },\n );\n case \"invalid_target\":\n verificationFail(\n \"Community branch verification could not be completed.\",\n \"community_verification_internal_error\",\n { statusCode: 500 },\n );\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.40.42",
3
+ "version": "0.40.43-nightly-20261029092708",
4
4
  "description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -90,7 +90,7 @@
90
90
  "tailwind-merge": "^3.5.0",
91
91
  "vaul": "^1.1.2",
92
92
  "zod": "^4.3.6",
93
- "@agent-native/toolkit": "0.222.0"
93
+ "@agent-native/toolkit": "0.222.1-nightly-20261029092708"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@react-router/dev": "^8.1.0",
@@ -104,10 +104,10 @@
104
104
  "typescript-7": "npm:typescript@^7.0.2",
105
105
  "vite": "8.1.0",
106
106
  "vitest": "^4.1.5",
107
- "@agent-native/core": "0.222.0"
107
+ "@agent-native/core": "0.222.1-nightly-20261029092708"
108
108
  },
109
109
  "peerDependencies": {
110
- "@agent-native/core": ">=0.222.0-0",
110
+ "@agent-native/core": "0.222.1-nightly-20261029092708",
111
111
  "react": ">=19.2.7",
112
112
  "react-dom": ">=19.2.7",
113
113
  "react-router": ">=8"
@@ -4,7 +4,10 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
4
4
 
5
5
  const mocks = vi.hoisted(() => {
6
6
  class MockBuilderBranchFilesError extends Error {
7
- constructor(readonly code: string) {
7
+ constructor(
8
+ readonly code: string,
9
+ readonly readbackStage?: string,
10
+ ) {
8
11
  super(code);
9
12
  }
10
13
  }
@@ -292,12 +295,29 @@ describe("verifyCuratedCommunityApp", () => {
292
295
 
293
296
  it("maps Builder read failures to typed errors without returning a receipt", async () => {
294
297
  mocks.readBuilderBranchFiles.mockRejectedValue(
295
- new BuilderBranchFilesError("unverified"),
298
+ new BuilderBranchFilesError("unverified", "status_currentness"),
296
299
  );
297
300
 
298
301
  await expect(verifyCuratedCommunityApp(input)).rejects.toMatchObject({
299
302
  errorCode: "community_verification_readback_unverified",
300
303
  statusCode: 422,
304
+ details: { readbackStage: "status_currentness" },
301
305
  });
302
306
  });
307
+
308
+ it("keeps older and unrecognized Core diagnostics explicitly unknown", async () => {
309
+ for (const error of [
310
+ new BuilderBranchFilesError("unverified"),
311
+ new BuilderBranchFilesError(
312
+ "unverified",
313
+ "https://provider.invalid/private",
314
+ ),
315
+ ]) {
316
+ mocks.readBuilderBranchFiles.mockRejectedValueOnce(error);
317
+ await expect(verifyCuratedCommunityApp(input)).rejects.toMatchObject({
318
+ errorCode: "community_verification_readback_unverified",
319
+ details: { readbackStage: "unknown" },
320
+ });
321
+ }
322
+ });
303
323
  });
@@ -44,11 +44,43 @@ export const communityInstallVerificationErrors = defineActionErrors(
44
44
  function verificationFail(
45
45
  message: string,
46
46
  code: Parameters<typeof communityInstallVerificationErrors.fail>[1],
47
- options: { statusCode: number },
47
+ options: { statusCode: number; details?: Record<string, unknown> },
48
48
  ): never {
49
49
  return communityInstallVerificationErrors.fail(message, code, options);
50
50
  }
51
51
 
52
+ const READBACK_STAGES = new Set([
53
+ "status_request",
54
+ "status_shape",
55
+ "status_binding",
56
+ "status_currentness",
57
+ "post_read_status_request",
58
+ "post_read_status_shape",
59
+ "post_read_status_binding",
60
+ "post_read_status_currentness",
61
+ "download_url_request",
62
+ "download_url_shape",
63
+ "download_url_binding",
64
+ "bundle_download",
65
+ "bundle_read",
66
+ "bundle_digest",
67
+ "bundle_parse",
68
+ "target_subtree_missing",
69
+ "post_read_currentness",
70
+ "app_integrity",
71
+ "snapshot_ref",
72
+ ]);
73
+
74
+ function readbackStage(error: unknown): string {
75
+ const stage =
76
+ error && typeof error === "object"
77
+ ? (error as { readbackStage?: unknown }).readbackStage
78
+ : undefined;
79
+ return typeof stage === "string" && READBACK_STAGES.has(stage)
80
+ ? stage
81
+ : "unknown";
82
+ }
83
+
52
84
  function requireHumanOrgOwner(): { orgId: string; ownerEmail: string } {
53
85
  const context = getRequestContext();
54
86
  const orgId = currentOrgId();
@@ -180,7 +212,7 @@ function failBranchReadback(error: unknown): never {
180
212
  verificationFail(
181
213
  "Builder could not provide a complete, identity-bound branch snapshot.",
182
214
  "community_verification_readback_unverified",
183
- { statusCode: 422 },
215
+ { statusCode: 422, details: { readbackStage: readbackStage(error) } },
184
216
  );
185
217
  }
186
218
  if (error.code === "invalid_request") {
@@ -194,7 +226,10 @@ function failBranchReadback(error: unknown): never {
194
226
  verificationFail(
195
227
  "Builder branch readback is unavailable. Try again later.",
196
228
  "community_verification_readback_unavailable",
197
- { statusCode: 503 },
229
+ {
230
+ statusCode: 503,
231
+ details: { readbackStage: readbackStage(error) },
232
+ },
198
233
  );
199
234
  }
200
235
 
@@ -273,14 +308,14 @@ export async function verifyCuratedCommunityApp(input: {
273
308
  verificationFail(
274
309
  "Builder branch files do not match the reviewed community template.",
275
310
  "community_verification_integrity_failed",
276
- { statusCode: 422 },
311
+ { statusCode: 422, details: { readbackStage: "app_integrity" } },
277
312
  );
278
313
  case "ref_mismatch":
279
314
  case "invalid_snapshot":
280
315
  verificationFail(
281
316
  "Builder could not provide a complete, identity-bound branch snapshot.",
282
317
  "community_verification_readback_unverified",
283
- { statusCode: 422 },
318
+ { statusCode: 422, details: { readbackStage: "snapshot_ref" } },
284
319
  );
285
320
  case "invalid_source":
286
321
  verificationFail(