@agent-native/core 0.213.1 → 0.216.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/action.js +54 -1
- package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
- package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
- package/dist/agent/actions/manage-builder-connection.js +5 -0
- package/dist/agent/actions/manage-provider-key-policy.js +5 -0
- package/dist/agent/actions/manage-provider-models.js +5 -0
- package/dist/agent/actions/manage-service-providers.js +5 -0
- package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
- package/dist/agent/context-xray/actions/context-evict.js +5 -0
- package/dist/agent/context-xray/actions/context-pin.js +5 -0
- package/dist/agent/context-xray/actions/context-report.js +5 -0
- package/dist/agent/context-xray/actions/context-restore.js +5 -0
- package/dist/agent/execution-fence.d.ts +1 -0
- package/dist/agent/execution-fence.js +5 -0
- package/dist/agent/production-agent.d.ts +35 -2
- package/dist/agent/production-agent.js +629 -32
- package/dist/agent/run-manager.d.ts +2 -0
- package/dist/agent/run-manager.js +397 -115
- package/dist/agent/run-slot-lock.d.ts +2 -0
- package/dist/agent/run-slot-lock.js +6 -0
- package/dist/agent/run-store.d.ts +5 -0
- package/dist/agent/run-store.js +423 -156
- package/dist/agent/thread-data-builder.js +27 -5
- package/dist/agent/types.d.ts +6 -12
- package/dist/agentkit/capabilities.d.ts +1 -1
- package/dist/appearance/actions/get-theme-family.d.ts +8 -0
- package/dist/appearance/actions/get-theme-family.js +38 -0
- package/dist/appearance/actions/set-theme-family.d.ts +7 -0
- package/dist/appearance/actions/set-theme-family.js +33 -0
- package/dist/appearance/theme-family.d.ts +13 -0
- package/dist/appearance/theme-family.js +38 -0
- package/dist/application-state/store.d.ts +5 -0
- package/dist/application-state/store.js +26 -0
- package/dist/chat-threads/schema-migrations.js +17 -0
- package/dist/chat-threads/store.d.ts +21 -1
- package/dist/chat-threads/store.js +223 -41
- package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
- package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
- package/dist/cli/templates-meta.js +14 -0
- package/dist/client/analytics.js +167 -17
- package/dist/client/chat/agentkit-agent-native.js +79 -3
- package/dist/client/chat/agentkit-protocol.js +80 -42
- package/dist/client/chat/runtime.d.ts +5 -1
- package/dist/client/chat/runtime.js +46 -3
- package/dist/client/consent.d.ts +36 -0
- package/dist/client/consent.js +283 -0
- package/dist/client/review/use-review.d.ts +2 -0
- package/dist/client/review/use-review.js +28 -1
- package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
- package/dist/client/sharing/useResourceAccessGate.js +9 -1
- package/dist/client/theme-family.d.ts +35 -0
- package/dist/client/theme-family.js +223 -0
- package/dist/client/theme.d.ts +1 -1
- package/dist/client/theme.js +5 -2
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/client/use-chat-thread-list.d.ts +2 -0
- package/dist/client/use-chat-thread-list.js +12 -2
- package/dist/client/use-chat-threads.d.ts +1 -0
- package/dist/client/use-chat-threads.js +2 -0
- package/dist/connections/catalog.d.ts +5 -5
- package/dist/connections/catalog.js +22 -3
- package/dist/data-widgets/index.d.ts +374 -5
- package/dist/data-widgets/index.js +242 -11
- package/dist/db/migrations.js +4 -1
- package/dist/db/schema-snapshot.generated.js +8 -1
- package/dist/feature-flags/actions/set-feature-flag.js +5 -0
- package/dist/feature-flags/index.d.ts +1 -1
- package/dist/feature-flags/index.js +1 -1
- package/dist/feature-flags/store.d.ts +12 -0
- package/dist/feature-flags/store.js +79 -7
- package/dist/file-upload/actions/manage-file-storage.js +5 -0
- package/dist/file-upload/actions/upload-image.js +5 -0
- package/dist/framework-tools.js +2 -0
- package/dist/history/actions/create-resource-version.js +5 -0
- package/dist/history/actions/restore-resource-version.js +5 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/index.js +1 -1
- package/dist/ingestion/pptx.d.ts +11 -0
- package/dist/ingestion/pptx.js +81 -1
- package/dist/integrations/actions/manage-messaging-channel.js +5 -0
- package/dist/jobs/scheduler.js +17 -1
- package/dist/labs/actions/set-lab.js +5 -0
- package/dist/localization/actions/set-localization-preference.js +5 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/observability/actions/save-observability-instruction-update.js +5 -0
- package/dist/observability/actions/save-observability-review-summary.js +5 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +19 -19
- package/dist/provider-api/actions/provider-api.d.ts +10 -10
- package/dist/provider-api/index.js +9 -2
- package/dist/review/actions/consume-review-feedback.js +5 -0
- package/dist/review/actions/create-review-comment.js +5 -0
- package/dist/review/actions/delete-review-comment.js +5 -0
- package/dist/review/actions/react-to-review-comment.js +5 -0
- package/dist/review/actions/reply-review-comment.js +5 -0
- package/dist/review/actions/resolve-review-thread.js +5 -0
- package/dist/review/actions/send-review-thread-to-agent.js +5 -0
- package/dist/review/actions/set-review-status.js +5 -0
- package/dist/review/actions/set-review-thread-muted.js +5 -0
- package/dist/review/actions/set-review-thread-unread.js +5 -0
- package/dist/review/actions/set-review-threads-unread.js +5 -0
- package/dist/review/actions/update-review-comment-anchor.js +5 -0
- package/dist/review/actions/update-review-comment.js +5 -0
- package/dist/review/suggestions/actions.js +60 -21
- package/dist/review/suggestions/store.d.ts +2 -0
- package/dist/review/suggestions/store.js +28 -0
- package/dist/secrets/actions/delete-api-key.js +5 -0
- package/dist/secrets/routes.d.ts +10 -10
- package/dist/server/action-discovery.js +8 -0
- package/dist/server/agent-chat/context-tools.js +105 -2
- package/dist/server/agent-chat-plugin.d.ts +2 -0
- package/dist/server/agent-chat-plugin.js +242 -54
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/application-state-maintenance.d.ts +2 -0
- package/dist/server/application-state-maintenance.js +2 -0
- package/dist/server/attribution.d.ts +14 -0
- package/dist/server/attribution.js +62 -2
- package/dist/server/auth.js +7 -0
- package/dist/server/consent-route.d.ts +41 -0
- package/dist/server/consent-route.js +102 -0
- package/dist/server/first-touch-route.d.ts +39 -0
- package/dist/server/first-touch-route.js +115 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
- package/dist/server/queued-submission-inbox-drain.js +12 -0
- package/dist/server/request-origin.d.ts +6 -0
- package/dist/server/request-origin.js +12 -0
- package/dist/settings/org-settings.d.ts +2 -1
- package/dist/settings/org-settings.js +4 -1
- package/dist/settings/store.d.ts +8 -0
- package/dist/settings/store.js +14 -5
- package/dist/shared/consent.d.ts +31 -0
- package/dist/shared/consent.js +145 -0
- package/dist/shared/first-touch-persistence.d.ts +31 -0
- package/dist/shared/first-touch-persistence.js +53 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +5 -0
- package/dist/sharing/actions/share-resource.js +5 -0
- package/dist/sharing/actions/unshare-resource.js +5 -0
- package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
- package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
- package/dist/usage/actions/get-usage-metrics.js +27 -4
- package/dist/usage/actions/manage-usage-alert.js +5 -0
- package/dist/vite/client.js +8 -6
- package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
- package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
- package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
- package/docs/content/actions-access-control.mdx +8 -8
- package/docs/content/actions-defining.mdx +9 -8
- package/docs/content/template-design-developers.mdx +9 -9
- package/docs/content/template-design-features.mdx +1 -3
- package/docs/content/turn-into-app.mdx +4 -0
- package/package.json +4 -3
- package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
- package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
|
@@ -13,53 +13,35 @@ record as history; the root remains held without a thread read or status reply.
|
|
|
13
13
|
Capture
|
|
14
14
|
the exact Slack actor ID used by the connected tool at sweep start. A mark is
|
|
15
15
|
owned by this task only when its reaction owner ID matches that actor ID. Each
|
|
16
|
-
unheld owned root needs a current
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
not fixed, unfixed, or broken. Use `Partially fixed` while any distinct scope
|
|
26
|
-
remains unfinished or a human/team handoff is still `unassigned` or `accepted`.
|
|
27
|
-
A completed handoff is retained history, not an open follow-up.
|
|
28
|
-
This is one current status reply per owned root, not a reply on every sweep.
|
|
29
|
-
Reuse the existing same-actor reply while its disposition and evidence remain
|
|
30
|
-
current; send an update when either materially changes. For a recent
|
|
31
|
-
unanswered reporter question, reuse the existing same-actor question/update as
|
|
32
|
-
the status reply when it states the disposition and evidence. If it does not,
|
|
33
|
-
post at most one concise status update that points to the existing unanswered
|
|
34
|
-
question without asking it again; then wait silently. Do not send another
|
|
35
|
-
question or progress ping before the four-day rule below. When a disposition
|
|
36
|
-
includes human handoffs, the status reply must name each handoff's recorded
|
|
37
|
-
owner and action; include its scope when the report context does not make it
|
|
38
|
-
clear.
|
|
16
|
+
unheld owned root needs a current same-actor status reply under the same parent.
|
|
17
|
+
Reuse it while the disposition remains current; send one short update when it
|
|
18
|
+
materially changes. Write one short sentence in plain, non-technical language,
|
|
19
|
+
then end with the exact bot disclosure
|
|
20
|
+
`this was sent from a bot.` Say what changed. Use `🎫` only for unresolved
|
|
21
|
+
work; when it is used, briefly say what still needs investigation or action and
|
|
22
|
+
name its owner when known. Do not explain absent reactions or mention a closed,
|
|
23
|
+
historical `🎫`. Keep scope, evidence, and handoff details in the internal
|
|
24
|
+
ledger.
|
|
39
25
|
|
|
40
|
-
|
|
26
|
+
Do not send a routine second reply just to announce a merge or publication.
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
answer, or four-day abandonment; label it historical in the current reply
|
|
50
|
-
and inventory when it no longer blocks progress.
|
|
28
|
+
For a recent unanswered reporter question, reuse the existing same-actor
|
|
29
|
+
question/update as the status reply when it still reflects the disposition. If
|
|
30
|
+
it does not, post at most one concise update that points to the question
|
|
31
|
+
without asking it again; then wait silently. Do not send another question or
|
|
32
|
+
progress ping before the four-day rule below. An evidence-only addendum or
|
|
33
|
+
correction is not a current status; edit it into a concise disposition when
|
|
34
|
+
possible, or send one status after the latest human reply.
|
|
51
35
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
and each `🎫` action with its owner or why none applies. Keep the exact bot
|
|
62
|
-
disclosure and read the visible final reply and root reactions back.
|
|
36
|
+
Keep full proof, scope, and handoff details in the internal ledger. When an
|
|
37
|
+
active `🎫` action remains, record its brief plain-language summary as
|
|
38
|
+
`statusReply.pendingActionSummary` and include that summary in the short reply.
|
|
39
|
+
When `unfinishedScopes` is nonempty, also record a brief
|
|
40
|
+
`statusReply.unfinishedScopeSummary` that names remaining work using wording
|
|
41
|
+
grounded in its recorded scope or evidence and says it is still open; include it
|
|
42
|
+
in the public reply even when there is no active `🎫`.
|
|
43
|
+
Do not explain absent reactions or list every scope. End with the exact bot
|
|
44
|
+
disclosure and read the visible reply and root reactions back.
|
|
63
45
|
|
|
64
46
|
When editing an ordinary Slack reply, pass its visible body as
|
|
65
47
|
`message.markdown_text` to `slack_edit_message`; `message.text` is a fallback
|
|
@@ -166,7 +148,8 @@ then immediately update and read back each applicable root reaction before
|
|
|
166
148
|
advancing to the next report. Add `✅` as soon as any reported scope passes the
|
|
167
149
|
direct post-change proof bar, including before merge; use
|
|
168
150
|
**Partially fixed** for the overall disposition when another scope remains,
|
|
169
|
-
and
|
|
151
|
+
and record both scopes in the internal ledger. Keep the reply short; do not
|
|
152
|
+
wait for an entire
|
|
170
153
|
multi-symptom report to be resolved before checking off its verified scope.
|
|
171
154
|
Keep all existing reactions after scopes close. Post the final disposition and
|
|
172
155
|
read back the final reply and reactions; the status shows closure while the
|
|
@@ -174,7 +157,7 @@ eye remains as history. Never remove or clean up any reaction. An open PR can
|
|
|
174
157
|
earn `✅` as soon as the relevant
|
|
175
158
|
`verifying-changes` proof bar passes. During that period, `✅` marks the
|
|
176
159
|
verified scope and `👀` may remain whether or not another scope or merge is
|
|
177
|
-
open; the marks are independent. The
|
|
160
|
+
open; the marks are independent. The internal ledger records what remains.
|
|
178
161
|
For UI behavior, a focused
|
|
179
162
|
regression qualifies only if it exercises the changed component and asserts the
|
|
180
163
|
reported visible result or persisted state; callback-only assertions, mocked
|
|
@@ -182,24 +165,28 @@ children, class-name checks, and source inspection do not. For clipping,
|
|
|
182
165
|
wrapping, contrast, or alignment, inspect rendered geometry at the reported
|
|
183
166
|
viewport or replay the flow in the running app. Use an app/preview replay when
|
|
184
167
|
the regression does not meet that bar. For non-UI scopes, use the area-specific
|
|
185
|
-
action, query, or test proof.
|
|
186
|
-
checkmark records
|
|
168
|
+
action, query, or test proof. Record merge or rollout state in the internal
|
|
169
|
+
ledger; the checkmark records verified scope and does not claim it is shipped
|
|
170
|
+
or live.
|
|
187
171
|
Before leaving each report, compare verified scopes and human/team handoffs
|
|
188
172
|
with a fresh root-reaction read. Ensure one `✅` is present when any scope passed the
|
|
189
173
|
proof bar and one `🎫` whenever any distinct unfinished action requires another
|
|
190
174
|
person or team to act, even before ownership is assigned or accepted. Keep the
|
|
191
175
|
mark as history after completion; read back each changed root reaction and
|
|
192
|
-
verify its owner.
|
|
193
|
-
|
|
176
|
+
verify its owner. Record why a mark is absent in the internal ledger. Never
|
|
177
|
+
explain absent `👀` or `✅` in a Slack reply. Emoji text in a reply is not a
|
|
194
178
|
reaction. Preserve every existing reaction. If later proof invalidates a prior
|
|
195
179
|
checkmark, move that scope out of active `fixedScopes[]` and add a
|
|
196
180
|
`historicalReactionMarks[]` entry with `emoji`, `scope`, `reason`, and the exact
|
|
197
|
-
prior `previousStatus`; the
|
|
198
|
-
|
|
181
|
+
prior `previousStatus`; keep the explanation in the internal ledger rather
|
|
182
|
+
than the Slack reply. If the owner withdraws an accepted action
|
|
199
183
|
tracked by `🎫`, also preserve the exact earlier accepted `handoff` and owner
|
|
200
|
-
`withdrawalReply`, move it out of current `handoffs[]
|
|
201
|
-
in the
|
|
202
|
-
|
|
184
|
+
`withdrawalReply`, and move it out of current `handoffs[]`. Keep that history
|
|
185
|
+
in the internal ledger. Preserve the recorded evidence and historical action in
|
|
186
|
+
the ledger; do not repeat a closed handoff in Slack unless a current action
|
|
187
|
+
remains. When a recorded action has a validated `publicActionSummary`, it may
|
|
188
|
+
be used for a current `🎫` summary. The checker validates it against the
|
|
189
|
+
recorded action and captured thread; never remove or clean up a reaction.
|
|
203
190
|
Add `🎫` for each distinct unfinished team or engineering action that another
|
|
204
191
|
person or team must perform outside this workflow, whether or not a named
|
|
205
192
|
person has accepted it or an external tracker ticket exists. Record each such
|
|
@@ -245,8 +232,9 @@ Keep its original `scope`, `action`, `requestReply`, and ticket-bearing
|
|
|
245
232
|
`resolution: "answered"` and include the exact human `closureReply` from the
|
|
246
233
|
same thread. For an unanswered request,
|
|
247
234
|
set `resolution: "abandoned_no_answer"` only after four days with no later human
|
|
248
|
-
reply, and omit `closureReply`. The
|
|
249
|
-
action and explain why its mark remains
|
|
235
|
+
reply, and omit `closureReply`. The internal ledger must identify the
|
|
236
|
+
historical action and explain why its mark remains; do not explain it in the
|
|
237
|
+
Slack reply unless a current follow-up remains. Link an external tracker ticket only
|
|
250
238
|
if one already exists; do not create or promise one without authorization. If a
|
|
251
239
|
human later refuses the accepted action, preserve `🎫` as history and update
|
|
252
240
|
the status with the refusal and blocker.
|
|
@@ -282,10 +270,11 @@ do not send a second owner update. If another task owns it or ownership is
|
|
|
282
270
|
unclear, preserve the eye, record the source in the ledger, and stop. Keep
|
|
283
271
|
distinct scopes and their status clear.
|
|
284
272
|
|
|
285
|
-
Compare each reported symptom with the evidence.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
273
|
+
Compare each reported symptom with the evidence. If the report is only partly
|
|
274
|
+
fixed, say so briefly and keep the scope details in the ledger. Use one root
|
|
275
|
+
`✅` when at least one fixed scope is verified; it covers every
|
|
276
|
+
verified scope listed in `fixedScopes[]`, which the internal ledger must name
|
|
277
|
+
with its proof. Use one root `🎫` whenever at least one distinct unfinished action
|
|
289
278
|
requires another person to act; it covers the actions listed in `handoffs[]`
|
|
290
279
|
and active requests in `reporterRequests[]`. Handoffs include unassigned
|
|
291
280
|
actions and completed actions whose evidence and `status: "completed"` remain
|
|
@@ -299,18 +288,6 @@ team handoff also gets `🎫`. Do not create or promise an external tracker
|
|
|
299
288
|
ticket without authorization. Never imply a
|
|
300
289
|
partial fix resolved the whole report.
|
|
301
290
|
|
|
302
|
-
For beta app fixes, check the matching merge-triggered publisher and keep
|
|
303
|
-
details in the recap. Do not post a routine second reply for merge or rollout.
|
|
304
|
-
If a reporter-facing reply is otherwise due, link the merged PR and state the
|
|
305
|
-
beta status in plain language. Say it is live only after checking it there. If
|
|
306
|
-
publication is pending, say it should follow soon without an exact date. If
|
|
307
|
-
the app or behavior cannot be checked, name that limit. If the publisher is
|
|
308
|
-
missing or failed, give no ETA and name the next action and owner. Keep hashes,
|
|
309
|
-
branch names, CI, workflow details, and run IDs out of reporter replies. For
|
|
310
|
-
package work, distinguish the source PR from any release PR and registry proof;
|
|
311
|
-
source merge alone does not establish publication. Give no ETA for a pending
|
|
312
|
-
package release.
|
|
313
|
-
|
|
314
291
|
For every reply in each final full-thread snapshot, record a read-back of the
|
|
315
292
|
workflow reactions on that reply. If the connector shows `👀`, `✅`, or `🎫`,
|
|
316
293
|
call `slack_get_reactions` for the reply's own timestamp and record exact owner
|
|
@@ -140,6 +140,6 @@ export default defineAction({
|
|
|
140
140
|
|
|
141
141
|
When the gate is truthy and the call isn't yet approved, the loop emits an `approval_required` event and **stops the turn — `run()` never executes**. A predicate gates conditionally (e.g. only external recipients) and **fails closed**: a throw is treated as "approval required". It receives its own copy of the prepared snapshot of the validated arguments, defaults applied, and the approval binds to the snapshot's hash, so an approved call runs only with the arguments that were approved (a Date binds by its time). The human approves via the chat UI's Approve affordance, which re-issues the turn with the call's `approvalKey`, and only then does the action run.
|
|
142
142
|
|
|
143
|
-
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other HTTP caller (bearer or API key, MCP OAuth token, org service token,
|
|
143
|
+
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other direct HTTP caller (bearer or API key, MCP OAuth token, org service token, extension iframe, or mobile app) gets `409 approval_required`, and a service identity can never approve. A2A tasks use their separate approval flow. The task pauses until its owner approves, then replays the approved tool call under its approval lease. The shared client presents the capability with every write from a signed-in session (minted once per user, reused for nine minutes, never for reads or public pages), so a gated button works on its first request. A call without proof gets `403 ui_capability_required`; the client then re-mints and retries once, which is only the fallback for an expired or rejected capability. The agent loop, plan mode registry, HTTP action route, generated Workers entry, and MCP dispatch evaluate the gate through `preparedCallNeedsApproval`, so a throwing predicate asks there too. The local `pnpm action ...` CLI calls `handler.run()` directly and does not evaluate `needsApproval`. Treat it as a local development tool, not an approval boundary. A caller that must run unattended needs a different action, never a bypass of the gate.
|
|
144
144
|
|
|
145
145
|
**Keep approvals rare** — the default is off and almost every action should leave it off. The canonical example is Mail's `send-email` (`needsApproval: true`). See the `security` skill and the Human Approval doc.
|
|
@@ -140,6 +140,6 @@ export default defineAction({
|
|
|
140
140
|
|
|
141
141
|
When the gate is truthy and the call isn't yet approved, the loop emits an `approval_required` event and **stops the turn — `run()` never executes**. A predicate gates conditionally (e.g. only external recipients) and **fails closed**: a throw is treated as "approval required". It receives its own copy of the prepared snapshot of the validated arguments, defaults applied, and the approval binds to the snapshot's hash, so an approved call runs only with the arguments that were approved (a Date binds by its time). The human approves via the chat UI's Approve affordance, which re-issues the turn with the call's `approvalKey`, and only then does the action run.
|
|
142
142
|
|
|
143
|
-
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other HTTP caller (bearer or API key, MCP OAuth token, org service token,
|
|
143
|
+
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other direct HTTP caller (bearer or API key, MCP OAuth token, org service token, extension iframe, or mobile app) gets `409 approval_required`, and a service identity can never approve. A2A tasks use their separate approval flow. The task pauses until its owner approves, then replays the approved tool call under its approval lease. The shared client presents the capability with every write from a signed-in session (minted once per user, reused for nine minutes, never for reads or public pages), so a gated button works on its first request. A call without proof gets `403 ui_capability_required`; the client then re-mints and retries once, which is only the fallback for an expired or rejected capability. The agent loop, plan mode registry, HTTP action route, generated Workers entry, and MCP dispatch evaluate the gate through `preparedCallNeedsApproval`, so a throwing predicate asks there too. The local `pnpm action ...` CLI calls `handler.run()` directly and does not evaluate `needsApproval`. Treat it as a local development tool, not an approval boundary. A caller that must run unattended needs a different action, never a bypass of the gate.
|
|
144
144
|
|
|
145
145
|
**Keep approvals rare** — the default is off and almost every action should leave it off. The canonical example is Mail's `send-email` (`needsApproval: true`). See the `security` skill and the Human Approval doc.
|
|
@@ -13,15 +13,16 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
# Turn Into App
|
|
15
15
|
|
|
16
|
-
Give a proven workflow
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
in the UI. A form under a stepper bar is the failure to prevent.
|
|
16
|
+
Give a proven workflow an Agent-Native app face and agent brain. Start with
|
|
17
|
+
populated domain screens. Object controls send work to the agent; the object
|
|
18
|
+
shows progress and receives the result. Avoid form-under-stepper layouts.
|
|
20
19
|
|
|
21
20
|
## Host, source, and when to ask
|
|
22
21
|
|
|
23
22
|
### Classify the host
|
|
24
23
|
|
|
24
|
+
- Local scaffolding needs Node.js 22.22.0 or newer (including npm/npx) and
|
|
25
|
+
pnpm.
|
|
25
26
|
- **Local host**: a terminal, a filesystem, and a target checkout (Claude Code,
|
|
26
27
|
Codex, Cursor, or an Agent-Native agent that can edit files). Build the app in
|
|
27
28
|
that checkout with steps 1-6. Never call `start-workspace-app-creation` or
|
|
@@ -105,9 +106,8 @@ opens on a mapping or setup screen.
|
|
|
105
106
|
|
|
106
107
|
## Workflow
|
|
107
108
|
|
|
108
|
-
Copy
|
|
109
|
-
|
|
110
|
-
run one pass and list the open criteria.
|
|
109
|
+
Copy and update this checklist. Aim for 45 minutes; note the start time
|
|
110
|
+
(`date`). If review starts after 35 minutes, run one pass and list open criteria.
|
|
111
111
|
|
|
112
112
|
```text
|
|
113
113
|
- [ ] 0 Host classified, source picked
|
|
@@ -160,13 +160,12 @@ without waiting.
|
|
|
160
160
|
|
|
161
161
|
### 3. Create the real scaffold
|
|
162
162
|
|
|
163
|
-
Before the first command,
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
Before the first command, name the steps (install, scaffold, checks, dev server,
|
|
164
|
+
headless browser) and estimate work time from the source and host. Separate
|
|
165
|
+
external setup waits, so delays are expected.
|
|
166
166
|
|
|
167
|
-
Choose a short slug and never overwrite an
|
|
168
|
-
|
|
169
|
-
repository; say so when it sits inside another checkout):
|
|
167
|
+
Choose a short slug and never overwrite an app. Run standalone creation from
|
|
168
|
+
its parent directory, noting that the nested app is its own Git repository:
|
|
170
169
|
|
|
171
170
|
```bash
|
|
172
171
|
npx --yes @agent-native/core@latest create <slug> --standalone --template chat
|
|
@@ -182,11 +181,10 @@ from the workspace root:
|
|
|
182
181
|
pnpm exec agent-native add-app <slug> --template chat
|
|
183
182
|
```
|
|
184
183
|
|
|
185
|
-
Read the generated `AGENTS.md
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
dev server
|
|
189
|
-
template only when it materially fits.
|
|
184
|
+
Read the generated `AGENTS.md` and any `build-an-app` skill. This skill
|
|
185
|
+
overrides guidance that skips the design record, screenshots, or build; leaves
|
|
186
|
+
`DESIGN.md` unchanged; omits `AUTH_DISABLED` or says not to set it; or stops
|
|
187
|
+
the dev server. Use another first-party template only if it materially fits.
|
|
190
188
|
|
|
191
189
|
If a scaffold or install step fails, times out (no output for 5 minutes), or is
|
|
192
190
|
denied, the app does not exist yet. Retry once where a retry could help, then
|
|
@@ -195,6 +193,10 @@ hand-build the app in another stack, edit a pinned dependency version to force
|
|
|
195
193
|
an install, or continue in a half-created directory; a workaround the user
|
|
196
194
|
requests is named in the report.
|
|
197
195
|
|
|
196
|
+
Before resuming, inspect the target and verify completed stages. Tell the user
|
|
197
|
+
what exists, the next stage, and estimated active work; resume at the first
|
|
198
|
+
unverified stage without rerunning scaffolding or replacing completed work.
|
|
199
|
+
|
|
198
200
|
Then save the brief as `docs/brief.md`, append the domain surface's design to
|
|
199
201
|
`DESIGN.md` (UI direction guide, section 4), and follow
|
|
200
202
|
[the run and deploy guide](references/local-run-and-deploy.md) to set
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { defineAction } from "../../action.js";
|
|
3
|
-
import {
|
|
2
|
+
import { defineAction, fail } from "../../action.js";
|
|
3
|
+
import { isOrgMember } from "../../org/membership.js";
|
|
4
|
+
import { ALL_USAGE_APPS, canViewWorkspaceUsage, listAppUsageMetrics, USAGE_APP_FILTER_ALL, USAGE_APP_FILTER_CURRENT, } from "../metrics-store.js";
|
|
4
5
|
import { resolveUsageAppKey } from "../store.js";
|
|
5
6
|
function resolveAppSelection(app, appId) {
|
|
6
7
|
if (appId !== undefined) {
|
|
@@ -16,12 +17,17 @@ function resolveAppSelection(app, appId) {
|
|
|
16
17
|
return app;
|
|
17
18
|
}
|
|
18
19
|
export default defineAction({
|
|
19
|
-
description: '
|
|
20
|
+
description: 'Reports this workspace\'s own agent/LLM usage (Settings › Usage) for members of this organization only; it does NOT cover usage, credits, or activity of external customers, accounts, companies, or product usage, which belong to the app that owns that data (see <relevant-apps>, or search with describe-workspace-apps). Returns lookback totals, the daily trend (dailyBy feature, app, model and surface), top features, models, apps, chats and people, tool calls per day, and recent prompts, across every app unless app names one. Members see only their own usage; scope "workspace" (everyone in the organization) is for owners and admins. billing.unit identifies Builder.io credits, estimated dollars, mixed billing, or unknown.',
|
|
20
21
|
http: { method: "GET" },
|
|
21
22
|
schema: z.object({
|
|
22
23
|
sinceDays: z.coerce.number().int().min(1).max(365).default(30),
|
|
23
24
|
scope: z.enum(["me", "workspace"]).default("me"),
|
|
24
|
-
userEmail: z
|
|
25
|
+
userEmail: z
|
|
26
|
+
.string()
|
|
27
|
+
.trim()
|
|
28
|
+
.min(1)
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("Email of a member of this organization to filter usage to. Not for customers or other external accounts."),
|
|
25
31
|
app: z
|
|
26
32
|
.string()
|
|
27
33
|
.trim()
|
|
@@ -39,6 +45,23 @@ export default defineAction({
|
|
|
39
45
|
run: async ({ sinceDays, scope, userEmail, app, appId }, ctx) => {
|
|
40
46
|
if (!ctx?.userEmail)
|
|
41
47
|
throw new Error("Not authenticated.");
|
|
48
|
+
// scope "me" ignores userEmail, so only a workspace lookup is checked.
|
|
49
|
+
if (scope === "workspace" &&
|
|
50
|
+
userEmail &&
|
|
51
|
+
ctx.orgId &&
|
|
52
|
+
userEmail.toLowerCase() !== ctx.userEmail.toLowerCase()) {
|
|
53
|
+
// Unauthorized callers get one answer whether or not the email is a
|
|
54
|
+
// member, so the lookup cannot be used to probe the roster.
|
|
55
|
+
if (!(await canViewWorkspaceUsage({
|
|
56
|
+
ownerEmail: ctx.userEmail,
|
|
57
|
+
orgId: ctx.orgId,
|
|
58
|
+
}))) {
|
|
59
|
+
fail("Only organization owners and admins can look up another person's usage with get-usage-metrics. Usage, credits, or activity for customers, accounts, or companies belongs to the app that owns that data (see <relevant-apps> or run describe-workspace-apps with a query).", { errorCode: "usage_user_lookup_forbidden", statusCode: 403 });
|
|
60
|
+
}
|
|
61
|
+
if (!(await isOrgMember(ctx.orgId, userEmail))) {
|
|
62
|
+
fail(`${userEmail} is not a member of this organization. get-usage-metrics only covers this workspace's own agent usage; usage, credits, or activity for customers, accounts, or companies belongs to the app that owns that data (see <relevant-apps> or run describe-workspace-apps with a query).`, { errorCode: "usage_user_not_org_member", statusCode: 404 });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
42
65
|
const selection = resolveAppSelection(app, appId);
|
|
43
66
|
return listAppUsageMetrics({ sinceDays, scope, userEmail, builderCreditsEnabled: true }, {
|
|
44
67
|
ownerEmail: ctx.userEmail,
|
|
@@ -15,6 +15,11 @@ export default defineAction({
|
|
|
15
15
|
channels: z.array(channel).min(1).optional(),
|
|
16
16
|
enabled: z.boolean().optional(),
|
|
17
17
|
}),
|
|
18
|
+
mcpAnnotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
openWorldHint: false,
|
|
22
|
+
},
|
|
18
23
|
run: async ({ operation, scope, ruleId, appId, unit, period, limit, channels, enabled }, ctx) => {
|
|
19
24
|
if (!ctx?.userEmail)
|
|
20
25
|
throw new Error("Not authenticated.");
|
package/dist/vite/client.js
CHANGED
|
@@ -982,7 +982,6 @@ function getDefaultOptimizeDeps(cwd) {
|
|
|
982
982
|
specifier: "@modelcontextprotocol/ext-apps/app-bridge",
|
|
983
983
|
packageName: "@modelcontextprotocol/ext-apps",
|
|
984
984
|
},
|
|
985
|
-
{ specifier: "@paper-design/shaders-react" },
|
|
986
985
|
{ specifier: "@radix-ui/react-accordion" },
|
|
987
986
|
{ specifier: "@radix-ui/react-alert-dialog" },
|
|
988
987
|
{ specifier: "@radix-ui/react-aspect-ratio" },
|
|
@@ -3482,11 +3481,14 @@ const DEFAULT_VITE_WATCH_IGNORED_DIRS = new Set([
|
|
|
3482
3481
|
"build",
|
|
3483
3482
|
]);
|
|
3484
3483
|
export function defaultViteWatchIgnored(root) {
|
|
3485
|
-
return (file) =>
|
|
3486
|
-
.relative(root, file)
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3484
|
+
return (file) => {
|
|
3485
|
+
const segments = path.relative(root, file).split(/[\\/]/);
|
|
3486
|
+
return segments
|
|
3487
|
+
.slice(0, -1)
|
|
3488
|
+
.some((segment, index) => segment === ".generated" && index === 0 && segments[1] === "bridge"
|
|
3489
|
+
? false
|
|
3490
|
+
: DEFAULT_VITE_WATCH_IGNORED_DIRS.has(segment));
|
|
3491
|
+
};
|
|
3490
3492
|
}
|
|
3491
3493
|
function forceServeOnly(pluginOrPreset) {
|
|
3492
3494
|
if (Array.isArray(pluginOrPreset))
|
|
@@ -12,6 +12,11 @@ export default defineAction({
|
|
|
12
12
|
.describe("Workspace member email addresses to change."),
|
|
13
13
|
operation: z.enum(["add", "remove"]).describe("Membership operation."),
|
|
14
14
|
}),
|
|
15
|
+
mcpAnnotations: {
|
|
16
|
+
readOnlyHint: false,
|
|
17
|
+
destructiveHint: true,
|
|
18
|
+
openWorldHint: false,
|
|
19
|
+
},
|
|
15
20
|
run: async (args, ctx) => {
|
|
16
21
|
await assertWorkspaceUserGroupManager(ctx?.orgId, ctx?.userEmail);
|
|
17
22
|
return updateWorkspaceUserGroupMembers({
|
|
@@ -7,6 +7,11 @@ export default defineAction({
|
|
|
7
7
|
schema: z.object({
|
|
8
8
|
id: z.string().min(1).describe("User group ID to delete."),
|
|
9
9
|
}),
|
|
10
|
+
mcpAnnotations: {
|
|
11
|
+
readOnlyHint: false,
|
|
12
|
+
destructiveHint: true,
|
|
13
|
+
openWorldHint: false,
|
|
14
|
+
},
|
|
10
15
|
run: async ({ id }, ctx) => {
|
|
11
16
|
await assertWorkspaceUserGroupManager(ctx?.orgId, ctx?.userEmail);
|
|
12
17
|
const orgId = ctx?.orgId ?? "";
|
|
@@ -11,6 +11,11 @@ export default defineAction({
|
|
|
11
11
|
.default([])
|
|
12
12
|
.describe("Workspace member email addresses in this group."),
|
|
13
13
|
}),
|
|
14
|
+
mcpAnnotations: {
|
|
15
|
+
readOnlyHint: false,
|
|
16
|
+
destructiveHint: true,
|
|
17
|
+
openWorldHint: false,
|
|
18
|
+
},
|
|
14
19
|
run: async (args, ctx) => {
|
|
15
20
|
await assertWorkspaceUserGroupManager(ctx?.orgId, ctx?.userEmail);
|
|
16
21
|
return upsertWorkspaceUserGroup({
|
|
@@ -164,9 +164,9 @@ A handful of actions are too consequential to let the agent run on its own, like
|
|
|
164
164
|
|
|
165
165
|
When `needsApproval` is omitted, behavior is byte-for-byte unchanged. There is no extra cost on the common path.
|
|
166
166
|
|
|
167
|
-
This works the same way for legacy `parameters`-style actions and for schema-based actions.
|
|
167
|
+
This works the same way for legacy `parameters`-style actions and for schema-based actions. The in-app agent and sub-agents pause in the agent loop. MCP and A2A use their own approval flows.
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
Direct calls to the [HTTP API](/docs/http-api) cannot provide human approval. The action route runs a gated call only for the proven app UI or the app's MCP directory widget. Other direct HTTP callers receive a `409` with `errorCode: "approval_required"`, and a service identity cannot approve. The shared client sends a short-lived UI capability with signed-in writes. A call without proof receives `403` with `errorCode: "ui_capability_required"`, then the client mints the capability and retries once. A2A tasks use their own approval flow, not this HTTP response. The task pauses until its owner approves, then replays the approved tool call. The local `pnpm action ...` CLI calls `handler.run()` directly and does not evaluate `needsApproval`. Treat this field as an approval flow, not an authorization boundary.
|
|
170
170
|
|
|
171
171
|
### How the loop pauses {#loop}
|
|
172
172
|
|
|
@@ -403,12 +403,12 @@ A create action calls neither helper. It only needs to stamp `ownerEmail` (and `
|
|
|
403
403
|
|
|
404
404
|
The four mechanisms are not interchangeable:
|
|
405
405
|
|
|
406
|
-
| Mechanism | Question it answers | Applies to
|
|
407
|
-
| --------------------------------- | ----------------------------------------------------- |
|
|
408
|
-
| `access` | Does the caller hold the declared role or membership? | All six dispatch sites
|
|
409
|
-
| `authorize` | May this caller perform the operation at all? | All six dispatch sites
|
|
410
|
-
| `needsApproval` | Should a human approve this specific permitted call? |
|
|
411
|
-
| `accessFilter()`/`assertAccess()` | Which rows may this permitted caller see or write? | Inside `run()`, per query or row
|
|
406
|
+
| Mechanism | Question it answers | Applies to |
|
|
407
|
+
| --------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------- |
|
|
408
|
+
| `access` | Does the caller hold the declared role or membership? | All six dispatch sites |
|
|
409
|
+
| `authorize` | May this caller perform the operation at all? | All six dispatch sites |
|
|
410
|
+
| `needsApproval` | Should a human approve this specific permitted call? | Agent, MCP, A2A. HTTP gates unproven calls. Local CLI bypasses. |
|
|
411
|
+
| `accessFilter()`/`assertAccess()` | Which rows may this permitted caller see or write? | Inside `run()`, per query or row |
|
|
412
412
|
|
|
413
413
|
A restricted write action typically needs both `authorize` and a row check. The first keeps non-coaches out of the operation. The second keeps a coach out of another org's plan. The row check is `assertAccess()`, or `access` when the row's id is an input field. `needsApproval` is a separate axis. It never restricts who may call, only whether the agent may proceed unattended.
|
|
414
414
|
|
|
@@ -385,14 +385,15 @@ A network drop, a proxy's HTML error page, and a bare status line author no mess
|
|
|
385
385
|
|
|
386
386
|
### What each throw produces {#failure-shapes}
|
|
387
387
|
|
|
388
|
-
| Thrown from `run()`
|
|
389
|
-
|
|
|
390
|
-
| `fail(msg)`
|
|
391
|
-
| `fail(msg, { errorCode, statusCode, details })`
|
|
392
|
-
| `new ActionContractError(msg, { errorCode })`
|
|
393
|
-
| `new AgentActionStopError(msg)`
|
|
394
|
-
| `
|
|
395
|
-
|
|
|
388
|
+
| Thrown from `run()` | HTTP status | Response body | Reported to error tracking |
|
|
389
|
+
| ------------------------------------------------------------------ | ----------------- | ---------------------------------------------- | -------------------------- |
|
|
390
|
+
| `fail(msg)` | 400 | `{ error: msg, errorCode: "action_failed" }` | No |
|
|
391
|
+
| `fail(msg, { errorCode, statusCode, details })` | your `statusCode` | `{ error, errorCode, details }` | No |
|
|
392
|
+
| `new ActionContractError(msg, { errorCode })` | 409 | `{ error, errorCode, details }` | No |
|
|
393
|
+
| `new AgentActionStopError(msg)` | 500 | `{ error: msg }` | No |
|
|
394
|
+
| A PostgreSQL deadlock (`40P01`) or serialization failure (`40001`) | 409 | `{ error, errorCode: "transaction_conflict" }` | No |
|
|
395
|
+
| `new Error(msg)` | 500 | `{ error: "Internal server error" }` | Yes |
|
|
396
|
+
| Input that fails `schema` | 400 | `{ error: "Invalid action parameters..." }` | No |
|
|
396
397
|
|
|
397
398
|
`AgentActionStopError` is the one to throw when the agent should end its turn rather than read the failure and try again. `ActionContractError` is what `fail()` raises for you, so reach for it directly only when 409 is the status you want.
|
|
398
399
|
|
|
@@ -134,15 +134,15 @@ Every design-specific operation is a TypeScript file in
|
|
|
134
134
|
|
|
135
135
|
### Motion and shaders
|
|
136
136
|
|
|
137
|
-
| Action | What it does
|
|
138
|
-
| ------------------------ |
|
|
139
|
-
| `get-motion-timeline` | Read an element's motion timeline
|
|
140
|
-
| `apply-motion-edit` | Add or edit a keyframe on a motion timeline
|
|
141
|
-
| `remove-motion-timeline` | Remove a motion timeline
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
| Action | What it does |
|
|
138
|
+
| ------------------------ | ----------------------------------------------------- |
|
|
139
|
+
| `get-motion-timeline` | Read an element's motion timeline |
|
|
140
|
+
| `apply-motion-edit` | Add or edit a keyframe on a motion timeline |
|
|
141
|
+
| `remove-motion-timeline` | Remove a motion timeline |
|
|
142
|
+
| `get-shader` | Inspect native definitions and saved effect manifests |
|
|
143
|
+
| `edit-native-shader` | Apply, edit, approve, or remove native effects |
|
|
144
|
+
|
|
145
|
+
Native WebGPU effects use WGSL. Custom authoring uses `edit-native-shader` with `define-definition`, `get-shader` to read the saved `executionHash`, `approve-definition` with that `expectedExecutionHash`, then `apply` with the exact definition ID/version. Each edit requires `designId`, `fileId`, and the current `expectedVersionHash`. Re-read the file hash after each write. CPU schema validation does not compile GPU code, so verify the Design preview. Previously saved GLSL effects remain renderable and removable.
|
|
146
146
|
|
|
147
147
|
### Quality {#quality}
|
|
148
148
|
|
|
@@ -175,9 +175,7 @@ when they apply to the current selection:
|
|
|
175
175
|
|
|
176
176
|
- **Fill** and **Stroke**: color, gradient, or image paint, with a
|
|
177
177
|
document color palette to reuse existing colors.
|
|
178
|
-
- **Effects**:
|
|
179
|
-
code-backed shader effect with named sliders (speed, color, center
|
|
180
|
-
point) and a Code panel for the raw GLSL.
|
|
178
|
+
- **Effects**: Drop shadow, layer blur, background blur, and native WebGPU effects with editable properties. Shader creation opens the agent chat to author native WGSL. Previously saved GLSL effects remain renderable and removable.
|
|
181
179
|
- **Position & layout**, **Typography**, **Appearance** (corner radius,
|
|
182
180
|
blend mode, visibility): the standard per-element property groups.
|
|
183
181
|
- **Layout** and **Auto layout**: flex-style arrangement for a frame's
|
|
@@ -43,6 +43,10 @@ A host counts as local when it has a real working directory, a terminal, and a w
|
|
|
43
43
|
|
|
44
44
|
On a browser host the skill requires the Agent-Native Dispatch MCP connector (`https://dispatch.agent-native.com/mcp`, OAuth) and calls its `start-workspace-app-creation` action. The host cannot run or inspect the app, so the report stays pending or unverified until the branch Dispatch returns is built. The skill reports what Dispatch actually returned and never invents a branch URL. For a ChatGPT Project, or any host that only exposes MCP, put the skill instructions in the Project instructions or knowledge files.
|
|
45
45
|
|
|
46
|
+
## Local prerequisites
|
|
47
|
+
|
|
48
|
+
On a local host, install Node.js 22.22.0 or newer (which includes npm and npx) and pnpm before starting. Browser hosts use Dispatch and do not run these commands.
|
|
49
|
+
|
|
46
50
|
## Sources {#sources}
|
|
47
51
|
|
|
48
52
|
- **Threads.** The last concrete, repeatable job is the product.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.216.0",
|
|
4
4
|
"description": "The agentic application framework for building autonomous agents with intuitive UIs",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -527,6 +527,7 @@
|
|
|
527
527
|
"./client/changelog/use-changelog-seen": "./dist/client/changelog/use-changelog-seen.js",
|
|
528
528
|
"./client/chat-model-groups": "./dist/client/chat-model-groups.js",
|
|
529
529
|
"./client/client-status-requests": "./dist/client/client-status-requests.js",
|
|
530
|
+
"./client/consent": "./dist/client/consent.js",
|
|
530
531
|
"./client/context-xray/format": "./dist/client/context-xray/format.js",
|
|
531
532
|
"./client/dev-overlay/builtins": "./dist/client/dev-overlay/builtins.js",
|
|
532
533
|
"./client/error-reporting": "./dist/client/error-reporting.js",
|
|
@@ -727,8 +728,8 @@
|
|
|
727
728
|
"yaml": "^2.9.0",
|
|
728
729
|
"yjs": "^13.6.33",
|
|
729
730
|
"zod": "^4.3.6",
|
|
730
|
-
"@agent-native/
|
|
731
|
-
"@agent-native/
|
|
731
|
+
"@agent-native/agentkit": "^0.216.0",
|
|
732
|
+
"@agent-native/recap-cli": "^0.5.85"
|
|
732
733
|
},
|
|
733
734
|
"devDependencies": {
|
|
734
735
|
"@ai-sdk/anthropic": "^3.0.71",
|
|
@@ -140,6 +140,6 @@ export default defineAction({
|
|
|
140
140
|
|
|
141
141
|
When the gate is truthy and the call isn't yet approved, the loop emits an `approval_required` event and **stops the turn — `run()` never executes**. A predicate gates conditionally (e.g. only external recipients) and **fails closed**: a throw is treated as "approval required". It receives its own copy of the prepared snapshot of the validated arguments, defaults applied, and the approval binds to the snapshot's hash, so an approved call runs only with the arguments that were approved (a Date binds by its time). The human approves via the chat UI's Approve affordance, which re-issues the turn with the call's `approvalKey`, and only then does the action run.
|
|
142
142
|
|
|
143
|
-
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other HTTP caller (bearer or API key, MCP OAuth token, org service token,
|
|
143
|
+
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other direct HTTP caller (bearer or API key, MCP OAuth token, org service token, extension iframe, or mobile app) gets `409 approval_required`, and a service identity can never approve. A2A tasks use their separate approval flow. The task pauses until its owner approves, then replays the approved tool call under its approval lease. The shared client presents the capability with every write from a signed-in session (minted once per user, reused for nine minutes, never for reads or public pages), so a gated button works on its first request. A call without proof gets `403 ui_capability_required`; the client then re-mints and retries once, which is only the fallback for an expired or rejected capability. The agent loop, plan mode registry, HTTP action route, generated Workers entry, and MCP dispatch evaluate the gate through `preparedCallNeedsApproval`, so a throwing predicate asks there too. The local `pnpm action ...` CLI calls `handler.run()` directly and does not evaluate `needsApproval`. Treat it as a local development tool, not an approval boundary. A caller that must run unattended needs a different action, never a bypass of the gate.
|
|
144
144
|
|
|
145
145
|
**Keep approvals rare** — the default is off and almost every action should leave it off. The canonical example is Mail's `send-email` (`needsApproval: true`). See the `security` skill and the Human Approval doc.
|