@agent-native/core 0.214.0 → 0.217.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.
Files changed (196) hide show
  1. package/dist/action.js +54 -1
  2. package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
  3. package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
  4. package/dist/agent/actions/manage-builder-connection.js +5 -0
  5. package/dist/agent/actions/manage-provider-key-policy.js +5 -0
  6. package/dist/agent/actions/manage-provider-models.js +5 -0
  7. package/dist/agent/actions/manage-service-providers.js +5 -0
  8. package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
  9. package/dist/agent/context-xray/actions/context-evict.js +5 -0
  10. package/dist/agent/context-xray/actions/context-pin.js +5 -0
  11. package/dist/agent/context-xray/actions/context-report.js +5 -0
  12. package/dist/agent/context-xray/actions/context-restore.js +5 -0
  13. package/dist/agent/execution-fence.d.ts +1 -0
  14. package/dist/agent/execution-fence.js +5 -0
  15. package/dist/agent/production-agent.d.ts +35 -2
  16. package/dist/agent/production-agent.js +629 -32
  17. package/dist/agent/run-manager.d.ts +2 -0
  18. package/dist/agent/run-manager.js +397 -115
  19. package/dist/agent/run-slot-lock.d.ts +2 -0
  20. package/dist/agent/run-slot-lock.js +6 -0
  21. package/dist/agent/run-store.d.ts +5 -0
  22. package/dist/agent/run-store.js +423 -156
  23. package/dist/agent/thread-data-builder.js +27 -5
  24. package/dist/agent/types.d.ts +6 -12
  25. package/dist/agentkit/capabilities.d.ts +1 -1
  26. package/dist/app-config/analytics.js +1 -1
  27. package/dist/application-state/store.d.ts +5 -0
  28. package/dist/application-state/store.js +26 -0
  29. package/dist/automation/index.d.ts +1 -1
  30. package/dist/chat-threads/schema-migrations.js +17 -0
  31. package/dist/chat-threads/store.d.ts +21 -1
  32. package/dist/chat-threads/store.js +223 -41
  33. package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
  34. package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
  35. package/dist/cli/templates-meta.js +14 -0
  36. package/dist/client/analytics-session.d.ts +7 -0
  37. package/dist/client/analytics-session.js +27 -1
  38. package/dist/client/analytics.js +276 -31
  39. package/dist/client/chat/agentkit-agent-native.js +79 -3
  40. package/dist/client/chat/agentkit-protocol.js +80 -42
  41. package/dist/client/chat/runtime.d.ts +5 -1
  42. package/dist/client/chat/runtime.js +46 -3
  43. package/dist/client/consent.d.ts +48 -0
  44. package/dist/client/consent.js +413 -0
  45. package/dist/client/onboarding/index.d.ts +1 -0
  46. package/dist/client/onboarding/index.js +1 -0
  47. package/dist/client/onboarding/use-onboarding-checklist.d.ts +23 -0
  48. package/dist/client/onboarding/use-onboarding-checklist.js +115 -0
  49. package/dist/client/review/use-review.d.ts +2 -0
  50. package/dist/client/review/use-review.js +28 -1
  51. package/dist/client/session-replay.d.ts +1 -1
  52. package/dist/client/session-replay.js +142 -3
  53. package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
  54. package/dist/client/sharing/useResourceAccessGate.js +9 -1
  55. package/dist/client/use-chat-thread-list.d.ts +2 -0
  56. package/dist/client/use-chat-thread-list.js +12 -2
  57. package/dist/client/use-chat-threads.d.ts +1 -0
  58. package/dist/client/use-chat-threads.js +2 -0
  59. package/dist/collab/awareness.d.ts +2 -2
  60. package/dist/connections/catalog.d.ts +5 -5
  61. package/dist/connections/catalog.js +22 -3
  62. package/dist/data-widgets/index.d.ts +36 -2
  63. package/dist/data-widgets/index.js +94 -6
  64. package/dist/db/migrations.js +4 -1
  65. package/dist/db/schema-snapshot.generated.js +8 -1
  66. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  67. package/dist/feature-flags/index.d.ts +1 -1
  68. package/dist/feature-flags/index.js +1 -1
  69. package/dist/feature-flags/store.d.ts +12 -0
  70. package/dist/feature-flags/store.js +79 -7
  71. package/dist/file-upload/actions/manage-file-storage.js +5 -0
  72. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  73. package/dist/file-upload/actions/upload-image.js +5 -0
  74. package/dist/history/actions/create-resource-version.js +5 -0
  75. package/dist/history/actions/restore-resource-version.js +5 -0
  76. package/dist/ingestion/index.d.ts +1 -1
  77. package/dist/ingestion/index.js +1 -1
  78. package/dist/ingestion/pptx.d.ts +11 -0
  79. package/dist/ingestion/pptx.js +81 -1
  80. package/dist/integrations/actions/manage-messaging-channel.js +5 -0
  81. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  82. package/dist/jobs/scheduler.js +17 -1
  83. package/dist/labs/actions/set-lab.js +5 -0
  84. package/dist/localization/actions/set-localization-preference.js +5 -0
  85. package/dist/localization/consent-banner-messages.d.ts +16 -0
  86. package/dist/localization/consent-banner-messages.js +149 -0
  87. package/dist/localization/core-messages.js +4 -0
  88. package/dist/localization/default-messages.d.ts +1 -0
  89. package/dist/localization/default-messages.js +2 -0
  90. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  91. package/dist/notifications/routes.d.ts +2 -2
  92. package/dist/observability/actions/save-observability-instruction-update.js +5 -0
  93. package/dist/observability/actions/save-observability-review-summary.js +5 -0
  94. package/dist/observability/routes.d.ts +6 -6
  95. package/dist/onboarding/index.d.ts +2 -1
  96. package/dist/onboarding/index.js +1 -0
  97. package/dist/onboarding/plugin.js +55 -46
  98. package/dist/onboarding/status.d.ts +15 -0
  99. package/dist/onboarding/status.js +59 -0
  100. package/dist/onboarding/types.d.ts +12 -0
  101. package/dist/onboarding/types.js +2 -1
  102. package/dist/org/workspace-app-access.js +19 -9
  103. package/dist/progress/routes.d.ts +1 -1
  104. package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
  105. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  106. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  107. package/dist/provider-api/index.js +9 -2
  108. package/dist/resources/handlers.d.ts +1 -1
  109. package/dist/review/actions/consume-review-feedback.js +5 -0
  110. package/dist/review/actions/create-review-comment.js +5 -0
  111. package/dist/review/actions/delete-review-comment.js +5 -0
  112. package/dist/review/actions/react-to-review-comment.js +5 -0
  113. package/dist/review/actions/reply-review-comment.js +5 -0
  114. package/dist/review/actions/resolve-review-thread.js +5 -0
  115. package/dist/review/actions/send-review-thread-to-agent.js +5 -0
  116. package/dist/review/actions/set-review-status.js +5 -0
  117. package/dist/review/actions/set-review-thread-muted.js +5 -0
  118. package/dist/review/actions/set-review-thread-unread.js +5 -0
  119. package/dist/review/actions/set-review-threads-unread.js +5 -0
  120. package/dist/review/actions/update-review-comment-anchor.js +5 -0
  121. package/dist/review/actions/update-review-comment.js +5 -0
  122. package/dist/review/suggestions/actions.js +60 -21
  123. package/dist/review/suggestions/store.d.ts +2 -0
  124. package/dist/review/suggestions/store.js +28 -0
  125. package/dist/secrets/actions/delete-api-key.js +5 -0
  126. package/dist/secrets/routes.d.ts +6 -6
  127. package/dist/server/agent-capabilities.js +13 -6
  128. package/dist/server/agent-chat/context-tools.js +63 -2
  129. package/dist/server/agent-chat-plugin.d.ts +2 -0
  130. package/dist/server/agent-chat-plugin.js +242 -54
  131. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  132. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  133. package/dist/server/analytics.d.ts +0 -1
  134. package/dist/server/analytics.js +81 -20
  135. package/dist/server/application-state-maintenance.d.ts +2 -0
  136. package/dist/server/application-state-maintenance.js +2 -0
  137. package/dist/server/attribution.d.ts +14 -0
  138. package/dist/server/attribution.js +62 -2
  139. package/dist/server/auth.js +7 -0
  140. package/dist/server/builder-api-auth.d.ts +7 -0
  141. package/dist/server/builder-api-auth.js +24 -0
  142. package/dist/server/builder-oauth.d.ts +5 -1
  143. package/dist/server/builder-oauth.js +5 -0
  144. package/dist/server/consent-route.d.ts +41 -0
  145. package/dist/server/consent-route.js +102 -0
  146. package/dist/server/core-routes-plugin.d.ts +1 -1
  147. package/dist/server/first-touch-route.d.ts +39 -0
  148. package/dist/server/first-touch-route.js +115 -0
  149. package/dist/server/index.d.ts +2 -1
  150. package/dist/server/index.js +2 -1
  151. package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
  152. package/dist/server/queued-submission-inbox-drain.js +12 -0
  153. package/dist/server/request-origin.d.ts +6 -0
  154. package/dist/server/request-origin.js +12 -0
  155. package/dist/settings/org-settings.d.ts +2 -1
  156. package/dist/settings/org-settings.js +4 -1
  157. package/dist/settings/store.d.ts +8 -0
  158. package/dist/settings/store.js +14 -5
  159. package/dist/shared/consent.d.ts +33 -0
  160. package/dist/shared/consent.js +149 -0
  161. package/dist/shared/first-touch-persistence.d.ts +31 -0
  162. package/dist/shared/first-touch-persistence.js +53 -0
  163. package/dist/sharing/actions/set-resource-visibility.js +5 -0
  164. package/dist/sharing/actions/share-resource.js +5 -0
  165. package/dist/sharing/actions/unshare-resource.js +5 -0
  166. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  167. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  168. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  169. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  170. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  171. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  172. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  173. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
  174. package/dist/triggers/actions/manage-automation.d.ts +4 -4
  175. package/dist/usage/actions/get-usage-metrics.js +27 -4
  176. package/dist/usage/actions/manage-usage-alert.js +5 -0
  177. package/dist/vite/client.js +8 -6
  178. package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
  179. package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
  180. package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
  181. package/docs/content/actions-access-control.mdx +8 -8
  182. package/docs/content/actions-defining.mdx +9 -8
  183. package/docs/content/deployment-environment-variables.mdx +1 -1
  184. package/docs/content/environment-variables.mdx +1 -1
  185. package/docs/content/template-design-developers.mdx +9 -9
  186. package/docs/content/template-design-features.mdx +1 -3
  187. package/docs/content/turn-into-app.mdx +4 -0
  188. package/package.json +6 -3
  189. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  190. package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  191. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  192. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  193. package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  194. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  195. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  196. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
@@ -27,43 +27,43 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
27
27
  thumbsUpRate: number;
28
28
  avgEvalScore: number;
29
29
  } | {
30
+ ok?: undefined;
30
31
  error: string;
31
32
  message: string;
32
33
  summary?: undefined;
33
34
  spans?: undefined;
34
- ok?: undefined;
35
35
  } | {
36
+ ok?: undefined;
36
37
  message?: undefined;
37
38
  summary: import("./types.js").TraceSummary;
38
39
  spans: import("./types.js").TraceSpan[];
39
40
  error?: undefined;
40
- ok?: undefined;
41
41
  } | {
42
+ ok?: undefined;
42
43
  message?: undefined;
43
44
  summary?: undefined;
44
45
  spans?: undefined;
45
46
  traceMissing: true;
46
47
  id: string;
47
48
  error?: undefined;
48
- ok?: undefined;
49
49
  } | {
50
+ ok?: undefined;
50
51
  message?: undefined;
51
52
  summary?: undefined;
52
53
  spans?: undefined;
53
54
  traceMissing?: undefined;
54
55
  id: string;
55
56
  error?: undefined;
56
- ok?: undefined;
57
57
  } | {
58
+ ok?: undefined;
58
59
  message?: undefined;
59
60
  summary?: undefined;
60
61
  spans?: undefined;
61
62
  error: any;
62
- ok?: undefined;
63
63
  } | {
64
64
  message?: undefined;
65
65
  summary?: undefined;
66
66
  spans?: undefined;
67
- error?: undefined;
68
67
  ok: boolean;
68
+ error?: undefined;
69
69
  }>>;
@@ -1,5 +1,6 @@
1
1
  export { registerOnboardingStep, listOnboardingSteps } from "./registry.js";
2
- export type { OnboardingStep, OnboardingMethod, OnboardingMethodBadge, OnboardingFormField, OnboardingStepStatus, OnboardingCapability, OnboardingAppProfile, WorkspaceBuilderIncludedServiceId, WorkspaceBuilderOnlyServiceId, WorkspaceProviderServiceId, WorkspaceServiceId, } from "./types.js";
2
+ export { DEFAULT_ONBOARDING_CHECKLIST } from "./types.js";
3
+ export type { OnboardingStep, OnboardingMethod, OnboardingMethodBadge, OnboardingFormField, OnboardingStepStatus, OnboardingResolveContext, OnboardingCapability, OnboardingAppProfile, WorkspaceBuilderIncludedServiceId, WorkspaceBuilderOnlyServiceId, WorkspaceProviderServiceId, WorkspaceServiceId, } from "./types.js";
3
4
  export { WORKSPACE_SERVICES, workspaceServiceForCapability, type WorkspaceService, type WorkspaceServiceKind, } from "./workspace-services.js";
4
5
  export { getOnboardingAppProfile, resolveOnboardingAppId, } from "./app-profile.js";
5
6
  export { getOnboardingAppProfileForId } from "./app-profile-data.js";
@@ -1,4 +1,5 @@
1
1
  export { registerOnboardingStep, listOnboardingSteps } from "./registry.js";
2
+ export { DEFAULT_ONBOARDING_CHECKLIST } from "./types.js";
2
3
  export { WORKSPACE_SERVICES, workspaceServiceForCapability, } from "./workspace-services.js";
3
4
  export { getOnboardingAppProfile, resolveOnboardingAppId, } from "./app-profile.js";
4
5
  export { getOnboardingAppProfileForId } from "./app-profile-data.js";
@@ -11,11 +11,10 @@ import { getOnboardingRoleCategory, getOnboardingRoleTextForAnalytics, onboardin
11
11
  import { getUserProfile, updateUserOnboardingRole, } from "../user-profile/store.js";
12
12
  import { getOnboardingAppProfile } from "./app-profile.js";
13
13
  import { registerDefaultOnboardingSteps } from "./default-steps.js";
14
- import { listOnboardingSteps } from "./registry.js";
15
14
  import { SHARED_ONBOARDING_COOKIE, SHARED_ONBOARDING_COOKIE_MAX_AGE, decodeSharedOnboardingCookie, encodeSharedOnboardingCookie, hashOnboardingEmail, } from "./shared-cookie.js";
15
+ import { getOnboardingStepStatuses, isValidOnboardingChecklistName, onboardingDismissedKey, onboardingOverrideKey, readOnboardingDismissed, } from "./status.js";
16
+ import { DEFAULT_ONBOARDING_CHECKLIST, } from "./types.js";
16
17
  const ONBOARDING_PREFIX = "/_agent-native/onboarding";
17
- const OVERRIDE_KEY_PREFIX = "onboarding:override:";
18
- const DISMISSED_KEY = "onboarding:dismissed";
19
18
  async function resolveOnboardingContext(event) {
20
19
  const { getSession } = await import("../server/auth.js");
21
20
  const session = await getSession(event);
@@ -27,35 +26,15 @@ async function resolveOnboardingContext(event) {
27
26
  orgId: session.orgId ?? null,
28
27
  };
29
28
  }
30
- async function hasOverride(sessionId, stepId) {
31
- const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);
32
- return !!(val && val.complete);
33
- }
34
- async function serializeSteps(context, options = {}) {
35
- const steps = listOnboardingSteps();
36
- const serialized = await Promise.all(steps.map(async (step) => {
37
- if (!options.preview && step.isAvailable) {
38
- if (!(await step.isAvailable(context)))
39
- return null;
40
- }
41
- let complete = false;
42
- if (!options.preview) {
43
- complete = (await step.isComplete(context)) === true;
44
- if (!complete) {
45
- complete = await hasOverride(context.sessionId, step.id);
46
- }
47
- }
48
- return {
49
- id: step.id,
50
- title: step.title,
51
- description: step.description,
52
- order: step.order,
53
- required: step.required ?? false,
54
- complete,
55
- methods: step.methods,
56
- };
57
- }));
58
- return serialized.filter((step) => step !== null);
29
+ /** `undefined` when the request names no checklist; `null` when the name is invalid. */
30
+ function readChecklistParam(event) {
31
+ const raw = getQuery(event).checklist;
32
+ if (raw === undefined)
33
+ return undefined;
34
+ if (typeof raw !== "string" || !isValidOnboardingChecklistName(raw)) {
35
+ return null;
36
+ }
37
+ return raw;
59
38
  }
60
39
  function withOnboardingRequestContext(context, fn) {
61
40
  return runWithRequestContext({
@@ -73,9 +52,10 @@ function roleTrackingProperties(role) {
73
52
  function allRequiredComplete(statuses) {
74
53
  return statuses.filter((s) => s.required).every((s) => s.complete);
75
54
  }
76
- async function readDismissedFlag(sessionId) {
77
- const value = await appStateGet(sessionId, DISMISSED_KEY);
78
- return !!(value && value.dismissed);
55
+ // A progress checklist has no required steps, so "required complete" would be
56
+ // vacuously true while steps are still open.
57
+ function allStepsComplete(statuses) {
58
+ return statuses.length > 0 && statuses.every((s) => s.complete);
79
59
  }
80
60
  async function resolveSharedCompletionEnabled() {
81
61
  if (!getAppConfig().onboarding.sharedCompletion.enabled)
@@ -104,10 +84,15 @@ export function createOnboardingPlugin(options = {}) {
104
84
  setResponseStatus(event, 405);
105
85
  return { error: "Method not allowed" };
106
86
  }
87
+ const checklist = readChecklistParam(event);
88
+ if (checklist === null) {
89
+ setResponseStatus(event, 400);
90
+ return { error: "Invalid checklist" };
91
+ }
107
92
  const context = await resolveOnboardingContext(event);
108
93
  const query = getQuery(event);
109
94
  const preview = query.preview === "1" || query.preview === 1;
110
- return withOnboardingRequestContext(context, () => serializeSteps(context, { preview }));
95
+ return withOnboardingRequestContext(context, () => getOnboardingStepStatuses(context, { preview, checklist }));
111
96
  }
112
97
  const [id, action] = trimmed.split("/");
113
98
  if (action === "complete") {
@@ -120,7 +105,7 @@ export function createOnboardingPlugin(options = {}) {
120
105
  return { error: "id required" };
121
106
  }
122
107
  const { sessionId } = await resolveOnboardingContext(event);
123
- await appStatePut(sessionId, `${OVERRIDE_KEY_PREFIX}${id}`, { complete: true }, { requestSource: "agent" });
108
+ await appStatePut(sessionId, onboardingOverrideKey(id), { complete: true }, { requestSource: "agent" });
124
109
  return { ok: true, id };
125
110
  }
126
111
  return;
@@ -130,8 +115,14 @@ export function createOnboardingPlugin(options = {}) {
130
115
  setResponseStatus(event, 405);
131
116
  return { error: "Method not allowed" };
132
117
  }
118
+ const requested = readChecklistParam(event);
119
+ if (requested === null) {
120
+ setResponseStatus(event, 400);
121
+ return { error: "Invalid checklist" };
122
+ }
123
+ const checklist = requested ?? DEFAULT_ONBOARDING_CHECKLIST;
133
124
  const { sessionId } = await resolveOnboardingContext(event);
134
- await appStatePut(sessionId, DISMISSED_KEY, { dismissed: true, at: new Date().toISOString() }, { requestSource: "agent" });
125
+ await appStatePut(sessionId, onboardingDismissedKey(checklist), { dismissed: true, at: new Date().toISOString() }, { requestSource: "agent" });
135
126
  return { ok: true };
136
127
  }));
137
128
  getH3App(nitroApp).use(`${ONBOARDING_PREFIX}/reopen`, defineEventHandler(async (event) => {
@@ -139,8 +130,14 @@ export function createOnboardingPlugin(options = {}) {
139
130
  setResponseStatus(event, 405);
140
131
  return { error: "Method not allowed" };
141
132
  }
133
+ const requested = readChecklistParam(event);
134
+ if (requested === null) {
135
+ setResponseStatus(event, 400);
136
+ return { error: "Invalid checklist" };
137
+ }
138
+ const checklist = requested ?? DEFAULT_ONBOARDING_CHECKLIST;
142
139
  const { sessionId } = await resolveOnboardingContext(event);
143
- await appStatePut(sessionId, DISMISSED_KEY, { dismissed: false, at: new Date().toISOString() }, { requestSource: "agent" });
140
+ await appStatePut(sessionId, onboardingDismissedKey(checklist), { dismissed: false, at: new Date().toISOString() }, { requestSource: "agent" });
144
141
  return { ok: true };
145
142
  }));
146
143
  getH3App(nitroApp).use(`${ONBOARDING_PREFIX}/dismissed`, defineEventHandler(async (event) => {
@@ -148,15 +145,22 @@ export function createOnboardingPlugin(options = {}) {
148
145
  setResponseStatus(event, 405);
149
146
  return { error: "Method not allowed" };
150
147
  }
148
+ const checklist = readChecklistParam(event);
149
+ if (checklist === null) {
150
+ setResponseStatus(event, 400);
151
+ return { error: "Invalid checklist" };
152
+ }
151
153
  const context = await resolveOnboardingContext(event);
152
154
  return withOnboardingRequestContext(context, async () => {
153
- const [statuses, value] = await Promise.all([
154
- serializeSteps(context),
155
- appStateGet(context.sessionId, DISMISSED_KEY),
155
+ const [statuses, dismissed] = await Promise.all([
156
+ getOnboardingStepStatuses(context, { checklist }),
157
+ readOnboardingDismissed(context.sessionId, checklist),
156
158
  ]);
157
159
  return {
158
- dismissed: !!(value && value.dismissed),
159
- allComplete: allRequiredComplete(statuses),
160
+ dismissed,
161
+ allComplete: checklist === undefined
162
+ ? allRequiredComplete(statuses)
163
+ : allStepsComplete(statuses),
160
164
  };
161
165
  });
162
166
  }));
@@ -172,13 +176,18 @@ export function createOnboardingPlugin(options = {}) {
172
176
  setResponseStatus(event, 405);
173
177
  return { error: "Method not allowed" };
174
178
  }
179
+ const checklist = readChecklistParam(event);
180
+ if (checklist === null) {
181
+ setResponseStatus(event, 400);
182
+ return { error: "Invalid checklist" };
183
+ }
175
184
  const context = await resolveOnboardingContext(event);
176
185
  const query = getQuery(event);
177
186
  const preview = query.preview === "1" || query.preview === 1;
178
187
  return withOnboardingRequestContext(context, async () => {
179
188
  const [steps, dismissed] = await Promise.all([
180
- serializeSteps(context, { preview }),
181
- readDismissedFlag(context.sessionId),
189
+ getOnboardingStepStatuses(context, { preview, checklist }),
190
+ readOnboardingDismissed(context.sessionId, checklist ?? DEFAULT_ONBOARDING_CHECKLIST),
182
191
  ]);
183
192
  return {
184
193
  steps,
@@ -0,0 +1,15 @@
1
+ import { type OnboardingResolveContext, type OnboardingStepStatus } from "./types.js";
2
+ export declare function isValidOnboardingChecklistName(name: string): boolean;
3
+ /** The setup checklist keeps its original key so existing dismissals survive. */
4
+ export declare function onboardingDismissedKey(checklist: string): string;
5
+ export declare function onboardingOverrideKey(stepId: string): string;
6
+ export declare function readOnboardingDismissed(sessionId: string, checklist?: string): Promise<boolean>;
7
+ /**
8
+ * Resolves the steps of one checklist. A failing `isAvailable`, `isComplete`,
9
+ * or override read rejects instead of reporting a step as incomplete, so
10
+ * callers can tell "could not check" from "not done".
11
+ */
12
+ export declare function getOnboardingStepStatuses(context: OnboardingResolveContext, options?: {
13
+ preview?: boolean;
14
+ checklist?: string;
15
+ }): Promise<OnboardingStepStatus[]>;
@@ -0,0 +1,59 @@
1
+ import { appStateGet } from "../application-state/store.js";
2
+ import { listOnboardingSteps } from "./registry.js";
3
+ import { DEFAULT_ONBOARDING_CHECKLIST, } from "./types.js";
4
+ const OVERRIDE_KEY_PREFIX = "onboarding:override:";
5
+ const DISMISSED_KEY = "onboarding:dismissed";
6
+ const CHECKLIST_NAME_PATTERN = /^[a-z][a-z0-9-]{0,39}$/;
7
+ export function isValidOnboardingChecklistName(name) {
8
+ return CHECKLIST_NAME_PATTERN.test(name);
9
+ }
10
+ /** The setup checklist keeps its original key so existing dismissals survive. */
11
+ export function onboardingDismissedKey(checklist) {
12
+ return checklist === DEFAULT_ONBOARDING_CHECKLIST
13
+ ? DISMISSED_KEY
14
+ : `${DISMISSED_KEY}:${checklist}`;
15
+ }
16
+ export function onboardingOverrideKey(stepId) {
17
+ return `${OVERRIDE_KEY_PREFIX}${stepId}`;
18
+ }
19
+ async function hasOverride(sessionId, stepId) {
20
+ const val = await appStateGet(sessionId, onboardingOverrideKey(stepId));
21
+ return !!(val && val.complete);
22
+ }
23
+ export async function readOnboardingDismissed(sessionId, checklist = DEFAULT_ONBOARDING_CHECKLIST) {
24
+ const value = await appStateGet(sessionId, onboardingDismissedKey(checklist));
25
+ return !!(value && value.dismissed);
26
+ }
27
+ /**
28
+ * Resolves the steps of one checklist. A failing `isAvailable`, `isComplete`,
29
+ * or override read rejects instead of reporting a step as incomplete, so
30
+ * callers can tell "could not check" from "not done".
31
+ */
32
+ export async function getOnboardingStepStatuses(context, options = {}) {
33
+ const checklist = options.checklist ?? DEFAULT_ONBOARDING_CHECKLIST;
34
+ const steps = listOnboardingSteps().filter((step) => (step.checklist ?? DEFAULT_ONBOARDING_CHECKLIST) === checklist);
35
+ const serialized = await Promise.all(steps.map(async (step) => {
36
+ if (!options.preview && step.isAvailable) {
37
+ if (!(await step.isAvailable(context)))
38
+ return null;
39
+ }
40
+ let complete = false;
41
+ if (!options.preview) {
42
+ complete = (await step.isComplete(context)) === true;
43
+ if (!complete) {
44
+ complete = await hasOverride(context.sessionId, step.id);
45
+ }
46
+ }
47
+ return {
48
+ id: step.id,
49
+ title: step.title,
50
+ description: step.description,
51
+ order: step.order,
52
+ required: step.required ?? false,
53
+ complete,
54
+ ...(step.href ? { href: step.href } : {}),
55
+ methods: step.methods,
56
+ };
57
+ }));
58
+ return serialized.filter((step) => step !== null);
59
+ }
@@ -45,12 +45,23 @@ export type OnboardingMethod = (OnboardingMethodBase & {
45
45
  */
46
46
  kind: "file-storage";
47
47
  });
48
+ /** The checklist a step belongs to when it does not name one: credential and connection setup. */
49
+ export declare const DEFAULT_ONBOARDING_CHECKLIST = "setup";
48
50
  export interface OnboardingStep {
49
51
  id: string;
50
52
  title: string;
51
53
  description: string;
52
54
  order: number;
53
55
  required?: boolean;
56
+ /**
57
+ * Named checklist the step belongs to. The setup checklist (the default)
58
+ * and a progress checklist such as `getting-started` never share rows:
59
+ * each is served only when asked for by name.
60
+ */
61
+ checklist?: string;
62
+ /** In-app path a progress row opens so the user can complete the step. */
63
+ href?: string;
64
+ /** Progress steps that need no setup form pass an empty list. */
54
65
  methods: OnboardingMethod[];
55
66
  isAvailable?: (context?: OnboardingResolveContext) => boolean | Promise<boolean>;
56
67
  isComplete: (context?: OnboardingResolveContext) => boolean | Promise<boolean>;
@@ -67,6 +78,7 @@ export interface OnboardingStepStatus {
67
78
  order: number;
68
79
  required: boolean;
69
80
  complete: boolean;
81
+ href?: string;
70
82
  methods: OnboardingMethod[];
71
83
  }
72
84
  /** Services whose provider is picked per service (`manage-service-providers`). */
@@ -1 +1,2 @@
1
- export {};
1
+ /** The checklist a step belongs to when it does not name one: credential and connection setup. */
2
+ export const DEFAULT_ONBOARDING_CHECKLIST = "setup";
@@ -232,24 +232,28 @@ async function resolveHostedWorkspaceAppAuth(configuredDirectory, context, email
232
232
  const audience = canonicalA2AAudience(configuredDirectory);
233
233
  let stage = "org-domain-lookup-failed";
234
234
  try {
235
+ const requestContext = getRequestContext();
236
+ const delegatedMember = requestContext?.a2aIdentityAssurance === "org-member";
235
237
  const orgDomain = orgId ? await cachedOrgDomain(orgId) : null;
236
238
  const normalizedOrgDomain = orgDomain?.trim() || undefined;
237
239
  if (orgId && !normalizedOrgDomain) {
238
240
  return workspaceAppAccessUnavailable("org-domain-missing", { audience });
239
241
  }
240
- stage = "org-a2a-secret-lookup-failed";
241
- const orgSecret = orgId
242
+ stage = "token-signing-failed";
243
+ const deploymentSecret = readDeployCredentialEnv("A2A_SECRET")?.trim();
244
+ if (orgId && (delegatedMember || deploymentSecret)) {
245
+ stage = "org-a2a-secret-lookup-failed";
246
+ }
247
+ const orgSecret = orgId && (delegatedMember || deploymentSecret)
242
248
  ? (await cachedOrgA2ASecret(orgId))?.trim() || undefined
243
249
  : undefined;
244
- const deploymentSecret = readDeployCredentialEnv("A2A_SECRET")?.trim();
245
- const signingSecret = orgSecret || deploymentSecret;
250
+ stage = "token-signing-failed";
251
+ const signingSecret = delegatedMember ? orgSecret : deploymentSecret;
246
252
  if (!signingSecret) {
247
253
  return workspaceAppAccessUnavailable("a2a-secret-missing", { audience });
248
254
  }
249
- stage = "token-signing-failed";
250
- const requestContext = getRequestContext();
251
255
  let token;
252
- if (requestContext?.a2aIdentityAssurance === "org-member") {
256
+ if (delegatedMember) {
253
257
  if (!orgId ||
254
258
  !normalizedOrgDomain ||
255
259
  requestContext.orgId?.trim() !== orgId ||
@@ -273,9 +277,15 @@ async function resolveHostedWorkspaceAppAuth(configuredDirectory, context, email
273
277
  token = await signA2AOrgMemberDelegationToken(email, normalizedOrgDomain, orgSecret, audience);
274
278
  }
275
279
  else {
276
- token = await signA2AToken(email, normalizedOrgDomain, orgSecret, {
280
+ if (orgSecret && orgSecret === deploymentSecret) {
281
+ return workspaceAppAccessUnavailable("token-signing-failed", {
282
+ audience,
283
+ detail: "Organization and deployment A2A secrets must differ for user identity.",
284
+ });
285
+ }
286
+ token = await signA2AToken(email, normalizedOrgDomain, undefined, {
277
287
  expiresIn: "1m",
278
- preferGlobalSecret: false,
288
+ preferGlobalSecret: true,
279
289
  audience,
280
290
  extraClaims: {
281
291
  jti: randomUUID(),
@@ -2,6 +2,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
2
2
  error: string;
3
3
  ok?: undefined;
4
4
  } | {
5
- error?: undefined;
6
5
  ok: boolean;
6
+ error?: undefined;
7
7
  }>>;
@@ -76,7 +76,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
78
  message?: undefined;
79
- found?: undefined;
79
+ id?: undefined;
80
+ provider?: undefined;
81
+ deleted?: undefined;
80
82
  providers: {
81
83
  id: string;
82
84
  label: string;
@@ -87,47 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
87
89
  updatedAt: number;
88
90
  }[];
89
91
  count: number;
90
- provider?: undefined;
91
- deleted?: undefined;
92
+ found?: undefined;
92
93
  registered?: undefined;
93
- id?: undefined;
94
94
  label?: undefined;
95
95
  } | {
96
96
  message?: undefined;
97
- providers?: undefined;
97
+ id?: undefined;
98
98
  count?: undefined;
99
+ deleted?: undefined;
100
+ providers?: undefined;
99
101
  found: boolean;
100
102
  provider: import("../custom-registry.js").CustomProviderConfig;
101
- deleted?: undefined;
102
103
  registered?: undefined;
103
- id?: undefined;
104
104
  label?: undefined;
105
105
  } | {
106
106
  message?: undefined;
107
- providers?: undefined;
108
- count?: undefined;
109
107
  provider?: undefined;
108
+ count?: undefined;
109
+ deleted?: undefined;
110
+ providers?: undefined;
110
111
  found: boolean;
111
112
  id: string;
112
- deleted?: undefined;
113
113
  registered?: undefined;
114
114
  label?: undefined;
115
115
  } | {
116
116
  message?: undefined;
117
- found?: undefined;
118
- providers?: undefined;
119
- count?: undefined;
120
117
  provider?: undefined;
118
+ count?: undefined;
119
+ providers?: undefined;
120
+ found?: undefined;
121
121
  deleted: boolean;
122
122
  id: string;
123
123
  registered?: undefined;
124
124
  label?: undefined;
125
125
  } | {
126
- found?: undefined;
127
- providers?: undefined;
128
- count?: undefined;
129
126
  provider?: undefined;
127
+ count?: undefined;
130
128
  deleted?: undefined;
129
+ providers?: undefined;
130
+ found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -317,8 +317,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
317
317
  scope?: "org" | "user" | undefined;
318
318
  }, {
319
319
  id?: undefined;
320
- found?: undefined;
321
320
  deleted?: undefined;
321
+ provider?: undefined;
322
322
  providers: {
323
323
  id: string;
324
324
  label: string;
@@ -329,15 +329,15 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
329
329
  updatedAt: number;
330
330
  }[];
331
331
  count: number;
332
- provider?: undefined;
332
+ found?: undefined;
333
333
  registered?: undefined;
334
334
  label?: undefined;
335
335
  message?: undefined;
336
336
  } | {
337
337
  id?: undefined;
338
338
  deleted?: undefined;
339
- providers?: undefined;
340
339
  count?: undefined;
340
+ providers?: undefined;
341
341
  found: boolean;
342
342
  provider: import("../custom-registry.js").CustomProviderConfig;
343
343
  registered?: undefined;
@@ -345,30 +345,30 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
345
345
  message?: undefined;
346
346
  } | {
347
347
  deleted?: undefined;
348
- providers?: undefined;
349
- count?: undefined;
350
348
  provider?: undefined;
349
+ count?: undefined;
350
+ providers?: undefined;
351
351
  found: boolean;
352
352
  id: string;
353
353
  registered?: undefined;
354
354
  label?: undefined;
355
355
  message?: undefined;
356
356
  } | {
357
- found?: undefined;
358
- providers?: undefined;
359
- count?: undefined;
360
357
  provider?: undefined;
358
+ count?: undefined;
359
+ providers?: undefined;
360
+ found?: undefined;
361
361
  deleted: boolean;
362
362
  id: string;
363
363
  registered?: undefined;
364
364
  label?: undefined;
365
365
  message?: undefined;
366
366
  } | {
367
- found?: undefined;
368
367
  deleted?: undefined;
369
- providers?: undefined;
370
- count?: undefined;
371
368
  provider?: undefined;
369
+ count?: undefined;
370
+ providers?: undefined;
371
+ found?: undefined;
372
372
  registered: boolean;
373
373
  id: string;
374
374
  label: string;
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
73
73
  offset?: unknown;
74
74
  limit?: unknown;
75
75
  }, {
76
+ deleted?: undefined;
76
77
  jobs: {
77
78
  id: string;
78
79
  name: string;
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
83
84
  updatedAt: string;
84
85
  }[];
85
86
  total: number;
86
- deleted?: undefined;
87
87
  jobId?: undefined;
88
88
  } | {
89
89
  jobs?: undefined;
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
91
91
  deleted: boolean;
92
92
  jobId: string;
93
93
  } | {
94
+ deleted?: undefined;
94
95
  jobs?: undefined;
95
96
  total?: undefined;
96
- deleted?: undefined;
97
97
  jobId?: undefined;
98
98
  hits: Record<string, unknown>[];
99
99
  offset: number;
@@ -787,7 +787,14 @@ const PROVIDER_CONFIGS = {
787
787
  docsUrls: ["https://developers.google.com/drive/api/reference/rest/v3"],
788
788
  specUrls: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
789
789
  allowedHostSuffixes: ["googleapis.com"],
790
- templateUses: ["brain", "content", "slides", "dispatch", "analytics"],
790
+ templateUses: [
791
+ "brain",
792
+ "content",
793
+ "slides",
794
+ "slides-2",
795
+ "dispatch",
796
+ "analytics",
797
+ ],
791
798
  examples: [
792
799
  { label: "List files", method: "GET", path: "/files" },
793
800
  { label: "Get file metadata", method: "GET", path: "/files/{fileId}" },
@@ -843,7 +850,7 @@ const PROVIDER_CONFIGS = {
843
850
  ],
844
851
  specUrls: ["https://slides.googleapis.com/$discovery/rest?version=v1"],
845
852
  allowedHostSuffixes: ["googleapis.com"],
846
- templateUses: ["brain", "content", "slides", "dispatch"],
853
+ templateUses: ["brain", "content", "slides", "slides-2", "dispatch"],
847
854
  examples: [
848
855
  {
849
856
  label: "Get presentation with slides and speaker notes",
@@ -39,8 +39,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
39
39
  error: string;
40
40
  }>;
41
41
  export declare function handleDeleteResource(event: any): Promise<{
42
- error: string;
43
42
  ok?: undefined;
43
+ error: string;
44
44
  } | {
45
45
  error?: undefined;
46
46
  ok: boolean;
@@ -10,6 +10,11 @@ const schema = z.object({
10
10
  export default defineAction({
11
11
  description: "Mark review feedback as consumed by the agent or reviewer workflow.",
12
12
  schema,
13
+ mcpAnnotations: {
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: false,
17
+ },
13
18
  run: async (args, ctx) => {
14
19
  const actionCtx = ctx;
15
20
  await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");
@@ -40,6 +40,11 @@ const schema = z.object({
40
40
  export default defineAction({
41
41
  description: "Create an inline comment, annotation, or review thread for a resource. Body text supports inline Markdown without headings.",
42
42
  schema,
43
+ mcpAnnotations: {
44
+ readOnlyHint: false,
45
+ destructiveHint: false,
46
+ openWorldHint: true,
47
+ },
43
48
  run: async (args, ctx) => {
44
49
  const actionCtx = ctx;
45
50
  const access = await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "commenter");
@@ -12,6 +12,11 @@ const schema = z.object({
12
12
  export default defineAction({
13
13
  description: "Soft-delete a review comment.",
14
14
  schema,
15
+ mcpAnnotations: {
16
+ readOnlyHint: false,
17
+ destructiveHint: true,
18
+ openWorldHint: false,
19
+ },
15
20
  run: async (args, ctx) => {
16
21
  const actionCtx = ctx;
17
22
  const scope = {