@agent-native/core 0.203.2-nightly-20261007213109 → 0.204.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/a2a/handlers.js +57 -1
- package/dist/a2a/server.js +37 -1
- package/dist/action.d.ts +1 -0
- package/dist/action.js +26 -3
- package/dist/agent/contain-principal.d.ts +9 -0
- package/dist/agent/contain-principal.js +53 -0
- package/dist/agent/production-agent.js +32 -2
- package/dist/agent/run-manager.js +14 -2
- package/dist/agent/run-store.js +66 -12
- package/dist/audit/actions/export-audit-events.d.ts +1 -1
- package/dist/audit/actions/export-audit-events.js +2 -2
- package/dist/audit/actions/export-audit-ocsf.d.ts +11 -0
- package/dist/audit/actions/export-audit-ocsf.js +183 -0
- package/dist/audit/actions/list-audit-events.d.ts +1 -1
- package/dist/audit/actions/list-audit-events.js +3 -3
- package/dist/audit/config.d.ts +1 -1
- package/dist/audit/config.js +5 -1
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.js +1 -0
- package/dist/audit/ocsf.d.ts +70 -0
- package/dist/audit/ocsf.js +228 -0
- package/dist/audit/record.js +1 -1
- package/dist/audit/store.js +9 -2
- package/dist/audit/types.d.ts +12 -1
- package/dist/cli/agent.js +2 -11
- package/dist/cli/connect.js +7 -2
- package/dist/client/use-db-sync.d.ts +13 -0
- package/dist/client/use-db-sync.js +22 -1
- package/dist/coding-tools/run-code.js +22 -1
- package/dist/coding-tools/sandbox/local-child-process-adapter.js +20 -0
- package/dist/collab/client.js +36 -3
- package/dist/collab/routes.d.ts +9 -4
- package/dist/collab/routes.js +15 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.js +15 -8
- package/dist/deploy/workspace-deploy.js +88 -13
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/file-upload/builder.js +18 -4
- package/dist/framework-tools.js +3 -0
- package/dist/identity/rekey.js +6 -0
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/localization/core-messages/supplemental/ar-SA.js +15 -0
- package/dist/localization/core-messages/supplemental/de-DE.js +15 -0
- package/dist/localization/core-messages/supplemental/en-US.js +15 -0
- package/dist/localization/core-messages/supplemental/es-ES.js +15 -0
- package/dist/localization/core-messages/supplemental/fr-FR.js +15 -0
- package/dist/localization/core-messages/supplemental/hi-IN.js +15 -0
- package/dist/localization/core-messages/supplemental/ja-JP.js +15 -0
- package/dist/localization/core-messages/supplemental/ko-KR.js +15 -0
- package/dist/localization/core-messages/supplemental/pt-BR.js +15 -0
- package/dist/localization/core-messages/supplemental/zh-CN.js +15 -0
- package/dist/localization/core-messages/supplemental/zh-TW.js +15 -0
- package/dist/localization/mcp-settings-messages.d.ts +15 -0
- package/dist/mcp/actions/create-org-service-token.d.ts +8 -0
- package/dist/mcp/actions/create-org-service-token.js +93 -4
- package/dist/mcp/actions/list-org-service-tokens.d.ts +2 -0
- package/dist/mcp/actions/list-org-service-tokens.js +36 -8
- package/dist/mcp/actions/service-principal-input.d.ts +48 -0
- package/dist/mcp/actions/service-principal-input.js +102 -0
- package/dist/mcp/actions/set-service-principal-lifecycle.d.ts +15 -0
- package/dist/mcp/actions/set-service-principal-lifecycle.js +150 -0
- package/dist/mcp/actions/set-service-principal-policy.d.ts +14 -0
- package/dist/mcp/actions/set-service-principal-policy.js +105 -0
- package/dist/mcp/build-server.js +117 -13
- package/dist/mcp/connect-route.js +116 -4
- package/dist/mcp/connect-store.d.ts +7 -0
- package/dist/mcp/connect-store.js +21 -14
- package/dist/mcp-client/oauth-routes.js +2 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +7 -7
- package/dist/org/index.d.ts +2 -2
- package/dist/org/service-principal-guard.d.ts +64 -0
- package/dist/org/service-principal-guard.js +140 -0
- package/dist/org/service-principal-policy.d.ts +104 -0
- package/dist/org/service-principal-policy.js +272 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
- package/dist/provider-api/actions/provider-api.d.ts +13 -13
- package/dist/scripts/dev/index.js +2 -8
- package/dist/scripts/parse-args.d.ts +7 -0
- package/dist/scripts/parse-args.js +76 -0
- package/dist/scripts/utils.d.ts +1 -1
- package/dist/scripts/utils.js +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/action-discovery.js +16 -42
- package/dist/server/agent-chat/script-entries.js +3 -8
- package/dist/server/agent-chat-plugin.js +8 -42
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/auth.js +5 -2
- package/dist/server/core-routes-plugin.js +25 -6
- package/dist/server/google-oauth.js +8 -4
- package/dist/server/identity-sso.js +2 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/poll.d.ts +9 -0
- package/dist/server/poll.js +86 -7
- package/dist/server/query-echo-safe-redirect.d.ts +10 -0
- package/dist/server/query-echo-safe-redirect.js +102 -0
- package/dist/server/release-schema.js +4 -0
- package/dist/server/workspace-provider-oauth.js +2 -1
- package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -0
- package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -0
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +24 -25
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +33 -0
- package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -0
- package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -0
- package/dist/triggers/actions/manage-automation.d.ts +7 -7
- package/dist/vite/client.js +1 -0
- package/docs/content/audit-log.mdx +15 -0
- package/docs/content/external-agents-catalog.mdx +19 -0
- package/docs/content/http-api.mdx +21 -2
- package/docs/content/pr-visual-recap.mdx +3 -1
- package/docs/content/template-clips-embed.mdx +1 -1
- package/docs/content/turn-into-app.mdx +118 -0
- package/package.json +4 -4
- package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -0
- package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -0
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +24 -25
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +33 -0
- package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -0
- package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -0
|
@@ -21,8 +21,10 @@ Four phases, in order. Phase 0 comes before any investigation, not after.
|
|
|
21
21
|
2. **Fix** what the evidence actually proves, at the owning boundary.
|
|
22
22
|
3. **Reply**, under a hard question budget, then recap.
|
|
23
23
|
|
|
24
|
-
Output is fixes
|
|
25
|
-
|
|
24
|
+
Output is fixes. Reply in-thread for every workflow reaction added this run;
|
|
25
|
+
continuing work gets a concrete progress reply, and resolved work gets a final
|
|
26
|
+
reply after verification. Follow
|
|
27
|
+
[`slack-reaction-replies.md`](references/slack-reaction-replies.md).
|
|
26
28
|
|
|
27
29
|
## Slack channels
|
|
28
30
|
|
|
@@ -46,9 +48,10 @@ work, post one status reply with task link and remaining scope.
|
|
|
46
48
|
|
|
47
49
|
## Phase 0: claim what you are taking
|
|
48
50
|
|
|
49
|
-
For an eligible item
|
|
50
|
-
never remove it. Do not resume items excluded by
|
|
51
|
-
**In progress** only when work continues beyond
|
|
51
|
+
Resolve known duplicate clusters before claiming. For an eligible item, add
|
|
52
|
+
`👀` before investigation and never remove it. Do not resume items excluded by
|
|
53
|
+
the Slack ownership gate. Post **In progress** only when work continues beyond
|
|
54
|
+
this run.
|
|
52
55
|
|
|
53
56
|
**Defects are in scope: fix them or ask for the one detail needed to fix them.**
|
|
54
57
|
Investigate first; ask what they saw or did in plain language. Gather request
|
|
@@ -62,13 +65,16 @@ doesn't close a separate defect. Tie each reaction to the scope it marks.
|
|
|
62
65
|
|
|
63
66
|
### Reaction gate
|
|
64
67
|
|
|
65
|
-
`👀` is claim history; `✅` requires **Fixed** after
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
`👀` is claim history; `✅` requires **Fixed** after Phase 2 bars. Check each
|
|
69
|
+
reported symptom separately. For partial fixes, pair `✅` for verified scope
|
|
70
|
+
with `🎫` for any distinct unfinished scope that needs a human to take
|
|
71
|
+
ownership or act, whether or not a ticket exists. Link a verified ticket and
|
|
72
|
+
name its owner/action; without one, keep the handoff explicit in the reply and
|
|
73
|
+
ledger and say that an owner or ticket still needs to be assigned. Do not
|
|
74
|
+
create or promise a ticket without authorization. No `🎫` for fixed scope,
|
|
75
|
+
routine rollout, optional checks, subjective/out-of-scope, or unapproved work.
|
|
76
|
+
**Shipped**/**Live verified** alone don't earn `✅`. Never remove reactions.
|
|
77
|
+
Follow the reply reference before marking an item replied.
|
|
72
78
|
|
|
73
79
|
For every concrete objective defect, attempt to reproduce it before recording
|
|
74
80
|
an evidence limit or asking the reporter for more information. A screenshot,
|
|
@@ -89,7 +95,8 @@ means you found neither a fix nor a useful question; state why in the thread.
|
|
|
89
95
|
For eligible items, use one disposition per row; record it in the recap and, if
|
|
90
96
|
unstated, in the thread or linked work. Do not inspect gated items for status.
|
|
91
97
|
For clusters, post one owner status with each source permalink and
|
|
92
|
-
**Clustered**;
|
|
98
|
+
**Clustered**; do not mark duplicate non-owners separately. Give a distinct
|
|
99
|
+
question or update its own reaction and reply.
|
|
93
100
|
|
|
94
101
|
- **Terminal (keep this workflow's eye):** **Fixed**, **Shipped**, **Live
|
|
95
102
|
verified**, **Open - no question**, **Resolved elsewhere**, **Skipped**,
|
|
@@ -455,16 +462,8 @@ Share only new or useful information.
|
|
|
455
462
|
|
|
456
463
|
### After a PR merges
|
|
457
464
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
For beta app fixes, check the merge-triggered publisher run before giving the
|
|
461
|
-
normal few-hours ETA. This checks release-job status, not beta behavior. If it
|
|
462
|
-
succeeds, say what changed and that it'll be on beta in the next few hours.
|
|
463
|
-
Keep test environment, verification, publisher results, and rollout details out
|
|
464
|
-
of the reply; record evidence in the recap or PR. If the run is missing or
|
|
465
|
-
failed, omit the ETA and state what's done, the exact remaining action and owner,
|
|
466
|
-
and an existing ticket when available. Apply the Reaction gate before `🎫`.
|
|
467
|
-
For packages, state availability without verification details.
|
|
465
|
+
Follow [`slack-reaction-replies.md`](references/slack-reaction-replies.md) for
|
|
466
|
+
post-merge beta ETAs and package replies.
|
|
468
467
|
|
|
469
468
|
For a fixed behavior with a ticketed handoff, state the done behavior and
|
|
470
469
|
remaining action/owner/ticket separately; don't imply the fixed scope is open.
|
|
@@ -561,9 +560,9 @@ Questions asked: N/3 · Dropped at 4 days: N
|
|
|
561
560
|
Repeats of a prior Fixed claim: N (each with its earlier thread and failed fix)
|
|
562
561
|
Upvoted items in scope: N (built: N)
|
|
563
562
|
|
|
564
|
-
| Tracker/source or workflow run | Reporter/owner | Status | Repro or failed step | Pre/post/recovery | Run/SHA/target/version/artifact/runtime proof | Locales | Handoff (action/owner/ticket) |
|
|
563
|
+
| Tracker/source or workflow run | Reporter/owner | Status | Repro or failed step | Pre/post/recovery | Run/SHA/target/version/artifact/runtime proof | Locales | Handoff (action/owner/ticket) | Reply proof | Reactions |
|
|
565
564
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
566
|
-
| 18 / [thread](...) or [workflow run](...) | ... | <disposition> | steps; expected/actual or failed job/step | before/after/recovery run | source/tests/build/run/SHA/target/version/URL | updated/N/A/pending | none or action/owner/[ticket](...) |
|
|
565
|
+
| 18 / [thread](...) or [workflow run](...) | ... | <disposition> | steps; expected/actual or failed job/step | before/after/recovery run | source/tests/build/run/SHA/target/version/URL | updated/N/A/pending | none or action/owner/[ticket](...) | [reply](...) or blocker | 👀 claim; ✅ Fixed; 🎫 human handoff needed |
|
|
567
566
|
|
|
568
567
|
Sibling sweep: <fingerprint> - N hits, M fixed, K triaged
|
|
569
568
|
Tracker: <sheet/export and bounded range> - N rows enumerated, N ledgers complete
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Slack Reaction Replies
|
|
2
|
+
|
|
3
|
+
For every Slack item this run independently marks with a workflow reaction,
|
|
4
|
+
send one concise reply under the same parent with its disposition. A same-run
|
|
5
|
+
fix gets its final reply after verification; continuing work gets a concrete
|
|
6
|
+
progress reply. An earlier generic “taking a look” does not satisfy this
|
|
7
|
+
update.
|
|
8
|
+
|
|
9
|
+
Preserve cluster handling: identify known duplicates before claiming them;
|
|
10
|
+
represent duplicate non-owner threads by permalink and **Clustered** in one
|
|
11
|
+
owner-thread status. Do not react or reply in a non-owner thread unless a
|
|
12
|
+
distinct question or update needs its own disposition; if it does, react and
|
|
13
|
+
reply there as a separate item. If a duplicate is discovered only after this
|
|
14
|
+
run added `👀`, keep it and post a concise **Clustered** reply with the owner
|
|
15
|
+
permalink; never remove the reaction.
|
|
16
|
+
|
|
17
|
+
Compare each reported symptom with the evidence. State what is fixed and what
|
|
18
|
+
is not. Use `✅` only for verified fixed scope. Use `🎫` for each distinct
|
|
19
|
+
unfinished scope that needs a human to take ownership or act, whether or not a
|
|
20
|
+
ticket exists. Link a verified ticket and name its owner/action; if no ticket
|
|
21
|
+
or owner is assigned, state the exact handoff and that gap in the reply and
|
|
22
|
+
ledger. Do not create or promise a ticket without authorization. Never imply a
|
|
23
|
+
partial fix resolved the whole report.
|
|
24
|
+
|
|
25
|
+
For beta app fixes, check the matching merge-triggered publisher. While it is
|
|
26
|
+
queued or running, say what changed and that it should be on beta within about
|
|
27
|
+
24 hours. If it succeeds, report beta publication as complete; that does not
|
|
28
|
+
prove independent runtime behavior. If the run is missing or fails, omit the
|
|
29
|
+
ETA and state the next action and owner. Keep verification and rollout details
|
|
30
|
+
in the recap. For packages, state availability without verification details.
|
|
31
|
+
|
|
32
|
+
Read back the reaction and reply as the invoking identity before recording the
|
|
33
|
+
item as replied.
|
|
@@ -16,6 +16,7 @@ Rules:
|
|
|
16
16
|
- To override the inference on an unusual action (e.g. a `POST` that only reads), pass `readOnly: true` on the action definition.
|
|
17
17
|
- To let a mutating action run concurrently with other same-turn tool calls, pass `parallelSafe: true`. Only do this when the action is internally concurrency-safe and order-independent (for example, it uses an app-level lock or idempotent upsert semantics). Mutating actions remain serialized by default.
|
|
18
18
|
- If a successful call hands control to the user — it renders a question, an intake form, or anything else the turn must wait on — pass `endsTurn: true` and make it the first or only call in the turn. It stops subsequent model steps and later calls, but cannot undo calls emitted before it. Without it a completion guard sees a turn that legitimately paused as one that failed to finish. `endsTurn: true` also hides the action from MCP, WebMCP, and A2A callers by default (`isActionExposedToExternalAgents` in core `action.ts`) — an external host has no in-app chat to receive the answer on. Pass `mcpTool: true` alongside it only when an external caller can complete the same operation without that answer.
|
|
19
|
+
- MCP hosts read tool annotations to decide how carefully to treat a call. Every MCP catalog advertises declared `mcpAnnotations` (`readOnlyHint`, `destructiveHint`, `openWorldHint`, optional `idempotentHint`); otherwise `/mcp` derives only `readOnlyHint` and an approval-based `destructiveHint`. Declare them on any external write that removes, overwrites, or replaces user content — recoverable Trash included — and mark idempotency-key-guarded writes `idempotentHint: true`.
|
|
19
20
|
|
|
20
21
|
Agents do NOT need to call `refresh-screen` after a normal action — it's already handled. `refresh-screen` is only needed when the agent mutates data via a path the framework can't see (e.g. writing to an external system the app mirrors) or when the agent wants to pass a `scope` hint for narrower invalidation.
|
|
21
22
|
|
|
@@ -16,6 +16,7 @@ Rules:
|
|
|
16
16
|
- To override the inference on an unusual action (e.g. a `POST` that only reads), pass `readOnly: true` on the action definition.
|
|
17
17
|
- To let a mutating action run concurrently with other same-turn tool calls, pass `parallelSafe: true`. Only do this when the action is internally concurrency-safe and order-independent (for example, it uses an app-level lock or idempotent upsert semantics). Mutating actions remain serialized by default.
|
|
18
18
|
- If a successful call hands control to the user — it renders a question, an intake form, or anything else the turn must wait on — pass `endsTurn: true` and make it the first or only call in the turn. It stops subsequent model steps and later calls, but cannot undo calls emitted before it. Without it a completion guard sees a turn that legitimately paused as one that failed to finish. `endsTurn: true` also hides the action from MCP, WebMCP, and A2A callers by default (`isActionExposedToExternalAgents` in core `action.ts`) — an external host has no in-app chat to receive the answer on. Pass `mcpTool: true` alongside it only when an external caller can complete the same operation without that answer.
|
|
19
|
+
- MCP hosts read tool annotations to decide how carefully to treat a call. Every MCP catalog advertises declared `mcpAnnotations` (`readOnlyHint`, `destructiveHint`, `openWorldHint`, optional `idempotentHint`); otherwise `/mcp` derives only `readOnlyHint` and an approval-based `destructiveHint`. Declare them on any external write that removes, overwrites, or replaces user content — recoverable Trash included — and mark idempotency-key-guarded writes `idempotentHint: true`.
|
|
19
20
|
|
|
20
21
|
Agents do NOT need to call `refresh-screen` after a normal action — it's already handled. `refresh-screen` is only needed when the agent mutates data via a path the framework can't see (e.g. writing to an external system the app mirrors) or when the agent wants to pass a `scope` hint for narrower invalidation.
|
|
21
22
|
|
|
@@ -13,6 +13,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
13
13
|
executionEngine?: string;
|
|
14
14
|
executionCwd?: string;
|
|
15
15
|
}, {
|
|
16
|
+
deleted?: undefined;
|
|
17
|
+
enabled?: undefined;
|
|
16
18
|
created: boolean;
|
|
17
19
|
name: string;
|
|
18
20
|
scope: "organization" | "personal";
|
|
@@ -23,33 +25,31 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
23
25
|
reasoningEffort: "auto" | "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh";
|
|
24
26
|
webhookPath: string;
|
|
25
27
|
nextRun: string;
|
|
26
|
-
deleted?: undefined;
|
|
27
|
-
enabled?: undefined;
|
|
28
28
|
executionHostId?: undefined;
|
|
29
29
|
executionEngine?: undefined;
|
|
30
30
|
executionCwd?: undefined;
|
|
31
31
|
} | {
|
|
32
|
-
|
|
32
|
+
enabled?: undefined;
|
|
33
|
+
nextRun?: undefined;
|
|
33
34
|
created?: undefined;
|
|
35
|
+
scope?: undefined;
|
|
34
36
|
triggerType?: undefined;
|
|
35
37
|
event?: undefined;
|
|
36
38
|
deleted: boolean;
|
|
37
39
|
name: string;
|
|
38
|
-
enabled?: undefined;
|
|
39
40
|
schedule?: undefined;
|
|
40
41
|
timezone?: undefined;
|
|
41
42
|
reasoningEffort?: undefined;
|
|
42
43
|
executionHostId?: undefined;
|
|
43
44
|
executionEngine?: undefined;
|
|
44
45
|
executionCwd?: undefined;
|
|
45
|
-
nextRun?: undefined;
|
|
46
46
|
webhookPath?: undefined;
|
|
47
47
|
} | {
|
|
48
|
-
|
|
48
|
+
deleted?: undefined;
|
|
49
49
|
created?: undefined;
|
|
50
|
+
scope?: undefined;
|
|
50
51
|
triggerType?: undefined;
|
|
51
52
|
event?: undefined;
|
|
52
|
-
deleted?: undefined;
|
|
53
53
|
name: string;
|
|
54
54
|
enabled: boolean;
|
|
55
55
|
schedule: string;
|
package/dist/vite/client.js
CHANGED
|
@@ -1159,6 +1159,7 @@ function getAgentKitOptimizeDeps(cwd) {
|
|
|
1159
1159
|
"@agent-native/toolkit/app/agentkit/react/components",
|
|
1160
1160
|
"@agent-native/toolkit/app/agentkit/react/context",
|
|
1161
1161
|
"@agent-native/toolkit/app/agentkit/react/root",
|
|
1162
|
+
"@agent-native/toolkit/app/chat",
|
|
1162
1163
|
"@agent-native/toolkit/app/chat/agentkit-chat/index",
|
|
1163
1164
|
]
|
|
1164
1165
|
: []),
|
|
@@ -169,6 +169,21 @@ const { data } = useActionQuery("list-audit-events", {
|
|
|
169
169
|
|
|
170
170
|
The agent can call the same action — ask it "what did you change on this recording?" and it answers from the trail.
|
|
171
171
|
|
|
172
|
+
## Export to a SIEM (OCSF) {#ocsf}
|
|
173
|
+
|
|
174
|
+
**`export-audit-ocsf`** returns the organization's trail as [OCSF](https://schema.ocsf.io) 1.9.0 API Activity events (`class_uid` 6003), oldest first, for a SIEM to pull on a schedule. Owners and admins only, and it reads the same `org` and `admins` events as the organization audit log, never anyone's private rows.
|
|
175
|
+
|
|
176
|
+
| Input | Meaning |
|
|
177
|
+
| -------- | ------------------------------------------------------------ |
|
|
178
|
+
| `since` | Only events at or after this ISO 8601 timestamp or epoch ms. |
|
|
179
|
+
| `until` | Only events before this ISO 8601 timestamp or epoch ms. |
|
|
180
|
+
| `cursor` | The `nextCursor` from the previous page. |
|
|
181
|
+
| `limit` | Events per page, up to 500 (default 100). |
|
|
182
|
+
|
|
183
|
+
It returns `{ events, hasMore, nextCursor }`. Store every returned `nextCursor` and send it back on the next pull, including when `events` is empty; empty pages advance the ready watermark. The cursor replays a five-minute overlap to catch late commits, so deduplicate across pulls by `metadata.uid`. The newest five seconds are held back so a late-written row is never skipped.
|
|
184
|
+
|
|
185
|
+
Each event maps `status` to `status_id` (`success` is Success; `error` and `denied` are Failure, with `denied` also `action_id` Denied and a higher `severity_id`), the actor to `actor.user` (a service principal is type Service), the action to `api.operation`, and the target to `resources`. Run, task, parent-task, thread, turn, and app ids have no OCSF field, so they sit under `unmapped`. Call arguments are never exported.
|
|
186
|
+
|
|
172
187
|
## Privacy & retention {#privacy}
|
|
173
188
|
|
|
174
189
|
- **Redaction** — before any inputs are stored, credential-shaped keys and values (tokens, secrets, passwords, bearer strings) are stripped and oversized payloads truncated. The audit log never becomes a secondary store of secrets. Keep `summary` text free of sensitive data too.
|
|
@@ -236,6 +236,25 @@ from the request origin, so deployments should not hard-code a production
|
|
|
236
236
|
|
|
237
237
|
Once an agent is connected, it sees the [compact catalog](#catalog-tiers) by default: template-declared app actions plus the builtin cross-app verbs (`list_apps`, `open_app`, `ask_app`, and the app-only embed helper). Use `ask_app` to route a natural-language task through an app agent (the same cross-app entry point [A2A](/docs/a2a-protocol) uses).
|
|
238
238
|
|
|
239
|
+
### Tool annotations {#tool-annotations}
|
|
240
|
+
|
|
241
|
+
Every catalog advertises an action's declared `mcpAnnotations`, including the
|
|
242
|
+
optional `idempotentHint`. Declare them wherever the derived hints would
|
|
243
|
+
misstate the effect: moving an item to recoverable Trash still removes it from
|
|
244
|
+
view, so it is `destructiveHint: true`, and a call guarded by an idempotency
|
|
245
|
+
key is `idempotentHint: true`. Without a declaration, `/mcp` derives
|
|
246
|
+
`readOnlyHint` from `readOnly` and `destructiveHint` from `needsApproval` or
|
|
247
|
+
`publicAgent.isConsequential`.
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
mcpAnnotations: {
|
|
251
|
+
readOnlyHint: false,
|
|
252
|
+
destructiveHint: true,
|
|
253
|
+
idempotentHint: true,
|
|
254
|
+
openWorldHint: false,
|
|
255
|
+
},
|
|
256
|
+
```
|
|
257
|
+
|
|
239
258
|
### MCP Apps compatibility {#mcp-apps-compatibility}
|
|
240
259
|
|
|
241
260
|
Agent-Native apps also speak the official MCP Apps extension. When any action
|
|
@@ -60,7 +60,7 @@ The command still authenticates you in the browser first — minting requires or
|
|
|
60
60
|
| Who can mint | Any signed-in user | Org owner/admin only |
|
|
61
61
|
| Best for | Your own scripts, local dev | CI, bots, scheduled integrations |
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Personal tokens default to 365 days in the CLI device flow; to choose a lifetime from 1 to 365 days, use the app's Connect page at `https://<app>/mcp/connect`. Org service tokens also default to 365 days and accept `--ttl-days` values between 1 and 3650. If a machine cannot open a browser, the app's Connect page is the fallback: sign in there, copy the token, and pass it with `connect <url> --token <token>` or paste it directly into your secret store.
|
|
64
64
|
|
|
65
65
|
For a self-hosted, single-tenant app where per-person identity does not matter, the static `ACCESS_TOKEN` / `ACCESS_TOKENS` environment variables are the simplest option — see [Authentication — Static MCP Bearer Tokens](/docs/authentication#access-tokens).
|
|
66
66
|
|
|
@@ -223,7 +223,7 @@ The action ran exactly as it would have from chat or the UI — same validation,
|
|
|
223
223
|
|
|
224
224
|
Tokens are JWTs signed by the app and bound to that app's audience. A token minted for one app cannot call another.
|
|
225
225
|
|
|
226
|
-
- **Lifetime** — 365 days by default, `--ttl-days` between 1 and
|
|
226
|
+
- **Lifetime** — 365 days by default, `--ttl-days` between 1 and 3650. Shorter is better for anything that runs unattended.
|
|
227
227
|
- **Rotation** — mint the new token, deploy it to the caller, confirm traffic is flowing, then revoke the old one. There is no in-place rotation; the two tokens are independent and can overlap.
|
|
228
228
|
- **Revocation** — every token carries a `jti`, and revocation is a `jti` check on every request, so a revoked token stops working immediately. Use the `list-org-service-tokens` action to see names, who minted them, and last-used timestamps, then `revoke-org-service-token` with the id. Both are owner/admin-gated for writes; any org member can list.
|
|
229
229
|
- **Recovery** — the token value is never stored, only its `jti`. If you lose it, mint a new one and revoke the old.
|
|
@@ -242,6 +242,25 @@ Because `list-org-service-tokens` reports `lastUsedAt`, it doubles as a cleanup
|
|
|
242
242
|
|
|
243
243
|
</Callout>
|
|
244
244
|
|
|
245
|
+
## Service principals {#service-principals}
|
|
246
|
+
|
|
247
|
+
Each org service token is a **service principal**, and a governance record says who answers for it and what it may do. Owners and admins set it when minting (`create-org-service-token` takes optional `ownerEmail`, `team`, `riskTier`, `purpose`, and `allowedActions`) and change it later with `set-service-principal-policy`. `list-org-service-tokens` returns each principal's record in `principals`.
|
|
248
|
+
|
|
249
|
+
| Field | Meaning |
|
|
250
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
251
|
+
| `ownerEmail` | The accountable human. Defaults to the admin who minted the token. |
|
|
252
|
+
| `team`, `purpose` | Who to page and what the principal is for. |
|
|
253
|
+
| `riskTier` | `low`, `medium`, or `high`. |
|
|
254
|
+
| `lifecycle` | `active`, `suspended`, or `retired`. |
|
|
255
|
+
| `allowedActions` | `null` is unrestricted. A list is a deny-by-default grant of exact action names or a trailing `*` prefix pattern; an empty list grants nothing. |
|
|
256
|
+
|
|
257
|
+
- **Grant** — `tools/list` shows only the granted actions, and any call outside the grant is refused, whether it arrives over MCP, an HTTP action route, or an agent run the principal started with `ask-agent` or `ask_app`. Agent built-ins such as `tool-search` and `view-screen` are covered too, so name them in the grant if the principal needs them. The grant narrows what the `member` role already allows; it never adds access.
|
|
258
|
+
- **Suspend and resume** — `set-service-principal-lifecycle` with `suspended` refuses the principal on every request, refuses new agent runs for it, and aborts its in-flight runs. `active` resumes it. The MCP connect page (`/mcp/connect`) has the same suspend and resume controls. `retired` also revokes its tokens and cannot be undone.
|
|
259
|
+
- **Ungoverned** — a service token minted before governance has no record. It stays active and unrestricted until an admin sets a policy.
|
|
260
|
+
- **Fails closed** — if the policy cannot be read, the request is refused with a `503`, never admitted.
|
|
261
|
+
|
|
262
|
+
These actions are owner/admin-only and are not callable by the agent, so neither an agent nor a service token can loosen its own grant.
|
|
263
|
+
|
|
245
264
|
## When it 403s {#troubleshooting}
|
|
246
265
|
|
|
247
266
|
A `401` means the token was not accepted at all. A `403` means the token _was_ accepted and the request then failed an access check — a different problem with a different fix.
|
|
@@ -249,7 +249,7 @@ survives any individual leaving, the recaps it publishes are org-visible, and
|
|
|
249
249
|
any org owner or admin can list or revoke it. Mint one (org owner/admin only):
|
|
250
250
|
|
|
251
251
|
```bash
|
|
252
|
-
npx @agent-native/core@latest connect https://plan.agent-native.com --service-token pr-recap
|
|
252
|
+
npx @agent-native/core@latest connect https://plan.agent-native.com --service-token pr-recap --ttl-days 3650
|
|
253
253
|
```
|
|
254
254
|
|
|
255
255
|
The command authenticates you in the browser, then prints the service token
|
|
@@ -257,6 +257,8 @@ exactly once — store it as the `PLAN_RECAP_TOKEN` secret. Manage it later with
|
|
|
257
257
|
the `list-org-service-tokens` and `revoke-org-service-token` actions on the
|
|
258
258
|
Plans app.
|
|
259
259
|
|
|
260
|
+
That gives CI a 10-year lifetime while keeping the token revocable at any time.
|
|
261
|
+
|
|
260
262
|
**Solo: a personal token still works.** Mint it with `npx @agent-native/core@latest connect`
|
|
261
263
|
against your Plans app. For the hosted app, this also writes a local
|
|
262
264
|
publish-token file that `npx @agent-native/recap-cli@latest recap setup` can read:
|
|
@@ -43,7 +43,7 @@ npx @agent-native/core@latest connect https://clips.agent-native.com \
|
|
|
43
43
|
|
|
44
44
|
Copy the printed token directly into your product's server-side secret manager. The token is organization-owned, so it continues working if the person who minted it leaves the organization or revokes their personal tokens. It is never written to a local client configuration. Use a different service name for each integration so one caller can be revoked without breaking another.
|
|
45
45
|
|
|
46
|
-
`--ttl-days` accepts 1 to
|
|
46
|
+
`--ttl-days` accepts 1 to 3650 days and defaults to 365. The token acts as an organization member. It cannot create or revoke other service tokens or change organization settings.
|
|
47
47
|
|
|
48
48
|
## Request an intake URL
|
|
49
49
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Turn Into App"
|
|
3
|
+
description: "The /turn-into-app skill turns a thread, skill, spreadsheet, or Claude or ChatGPT project into a runnable Agent-Native app that opens on a populated, domain-shaped surface."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Turn Into App
|
|
7
|
+
|
|
8
|
+
`/turn-into-app` is a skill that turns a workflow you have already proven into an Agent-Native app. The source can be a thread, a skill, a spreadsheet, or a Claude or ChatGPT project. The app opens on your world, populated with sample data shaped like the source, with the in-app agent working behind controls on the objects it acts on. A form under a step bar is the result the skill is built to avoid.
|
|
9
|
+
|
|
10
|
+
## Install {#install}
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx @agent-native/skills@latest add --skill turn-into-app
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The same skill ships with the core CLI:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx @agent-native/core@latest skills add turn-into-app
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Inside a project that already has the Agent-Native CLI, `agent-native skills add turn-into-app` does the same thing. See the [Skills Guide](/docs/skills-guide) for how skills are installed and loaded.
|
|
23
|
+
|
|
24
|
+
## Invoke it {#invoke}
|
|
25
|
+
|
|
26
|
+
| Command | Source |
|
|
27
|
+
| ---------------------------------- | ----------------------------------------------------------- |
|
|
28
|
+
| `/turn-into-app` | The visible project context, otherwise the current thread |
|
|
29
|
+
| `/turn-into-app /some-skill` | The named skill, packaged immediately, even at thread start |
|
|
30
|
+
| `/turn-into-app ./forecast.xlsx` | A spreadsheet, turned into a workbench |
|
|
31
|
+
| `/turn-into-app ./project-export/` | A Claude or ChatGPT project export |
|
|
32
|
+
|
|
33
|
+
Without an argument the skill builds the latest successful, repeatable job and names it. A worked example, such as one account or one deal, is evidence for the job, not its schema. If no job can be identified, it says what is missing instead of asking a generic "what app do you want?" question.
|
|
34
|
+
|
|
35
|
+
## Where it runs {#hosts}
|
|
36
|
+
|
|
37
|
+
| Host | What happens |
|
|
38
|
+
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| Claude Code, Codex, Cursor, other local coding agents | Builds, runs, and reviews the app in your checkout. |
|
|
40
|
+
| Claude or ChatGPT on the web | Writes a bounded brief and hands it to Builder through the Dispatch connector. It does not run anything itself. |
|
|
41
|
+
|
|
42
|
+
A host counts as local when it has a real working directory, a terminal, and a workspace. Having a Builder or Dispatch connector does not make a host a browser host.
|
|
43
|
+
|
|
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
|
+
|
|
46
|
+
## Sources {#sources}
|
|
47
|
+
|
|
48
|
+
- **Threads.** The last concrete, repeatable job is the product.
|
|
49
|
+
- **Skills.** The skill's steps, human decision points, and read-only rules become the app. If the skill keeps plan files, those files stay the source of truth through Local File Mode and the app is local-only.
|
|
50
|
+
- **Spreadsheets.** Every worksheet is inventoried first. Structure decides which cells are inputs and outputs; color is only a weak hint. The workbook is never copied into a prompt, SQL, or application state. A Google Sheets link is only a source when it is readable through an authenticated Sheets or Drive connection; otherwise the skill asks for an export.
|
|
51
|
+
- **Claude and ChatGPT projects.** Visible instructions, knowledge files, and supplied past runs are the source. The connector does not read hidden project chats, private URLs, or credentials, and there is no shared-link importer. Attach an export when the context is not visible.
|
|
52
|
+
|
|
53
|
+
## What you get {#what-you-get}
|
|
54
|
+
|
|
55
|
+
- **A shape chosen from the source.** The skill picks one of 13 archetypes, such as a triage queue, pipeline board, live workbench, schedule grid, review diff, or monitor. The archetype is the object the user looks at, not the procedure they follow, so source steps become states on objects (Draft, Checked, Approved) rather than a stepper or wizard.
|
|
56
|
+
- **A named visual direction.** One of six directions (`ledger`, `control-room`, `paper-desk`, `studio-canvas`, `tidepool`, `signal-board`) with light and dark tokens, picked from the archetype and the source's domain. An existing brand or your explicit direction wins.
|
|
57
|
+
- **A populated first screen.** `/` lands on a named domain route with synthetic sample data, labeled as sample, shaped like the source. An empty state, a hero, the procedure's first step, or a form is a defect unless the source itself is form-shaped.
|
|
58
|
+
- **Agent moments on the objects.** Each AI-labeled control hands a bounded prompt to the agent sidebar. The object shows a working state right away, and the result lands back on it with Accept, Edit, and Retry. Follow-ups stay in the same thread.
|
|
59
|
+
- **A real Agent-Native app.** Deterministic work is `defineAction` files that both the UI and the agent call. The app uses the standard Use Builder.io or Custom keys setup, writes the current view and selection to application state, and has `AGENTS.md` teaching the in-app agent about the new app.
|
|
60
|
+
|
|
61
|
+
The skill saves its source brief as `docs/brief.md` and appends the surface design to `DESIGN.md`.
|
|
62
|
+
|
|
63
|
+
## How a run works {#how-it-works}
|
|
64
|
+
|
|
65
|
+
1. **Brief.** It reads the whole source and writes a short brief: the job, at most three agent moments, invariants, data hazards, source of truth, and assumptions.
|
|
66
|
+
2. **Design.** It decides the archetype, direction, shell, first viewport and sample data, and agent moments, and posts the brief once as a checkpoint. It continues without waiting.
|
|
67
|
+
3. **Scaffold.** It creates the real app with the chat template and never overwrites an existing app.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx --yes @agent-native/core@latest create <slug> --standalone --template chat
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Inside an existing Agent-Native workspace it runs `pnpm exec agent-native add-app <slug> --template chat` from the workspace root instead.
|
|
74
|
+
|
|
75
|
+
4. **Build.** Actions, the domain surface, sample data, agent moments, and agent instructions are built together.
|
|
76
|
+
5. **Review.** It runs the app and reviews screenshots. See below.
|
|
77
|
+
6. **Verify.** It runs `pnpm typecheck`, `pnpm agent-native:doctor`, and `pnpm build`, then writes the final report.
|
|
78
|
+
|
|
79
|
+
The skill aims for about 45 minutes. If 35 minutes have passed when the review starts, it runs one pass and lists the open criteria.
|
|
80
|
+
|
|
81
|
+
## The screenshot review loop {#review-loop}
|
|
82
|
+
|
|
83
|
+
Before handoff the skill starts the dev server and screenshots `/` at desktop and phone sizes in light and dark, plus the main agent control after a click. It scores the shots against a 12-row rubric covering first-viewport impact, domain fit, hierarchy, chrome discipline, sample data, typography, color, polish, agent and UI together, 390px layout, dark mode, and accessibility.
|
|
84
|
+
|
|
85
|
+
Some findings fail the review whatever the average score: a stepper or wizard shell, `/` not opening on the domain route, an empty or form-only first viewport, scaffold default tokens, clipped text, raw markdown, sideways scroll at 390px, or a console error. It fixes every finding in one batch, resets whatever the click changed, and shoots again. The default is two passes, with a third only if the second still misses the bar and time allows. The bar is a mean of 4.0 or higher with no criterion below 3 and no automatic fail.
|
|
86
|
+
|
|
87
|
+
Screenshots are saved in the app's `.tmp/ui-review/out/`, and the final report lists their paths and scores. A result landing in the UI can only be exercised with a connected AI provider; without one, the report says the result was not exercised.
|
|
88
|
+
|
|
89
|
+
## Run and deploy {#run-deploy}
|
|
90
|
+
|
|
91
|
+
For local review the skill sets `AUTH_DISABLED=1` in the app's ignored `.env`, because a fresh screenshot browser is not signed in. This is for loopback development only. It is removed before the final `pnpm build`, and it must never be committed or deployed. Without it, opening the app shows a "Continue as local dev" card.
|
|
92
|
+
|
|
93
|
+
To run the app yourself:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm dev
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
To use your own model provider locally, put a key such as `ANTHROPIC_API_KEY` in the same `.env`. Otherwise the agent sidebar shows the shared Use Builder.io or Custom keys setup.
|
|
100
|
+
|
|
101
|
+
The skill deploys only when you ask or the provider is already configured. A healthy local build still prints a "production configuration errors" block with exit code 0. That is the deploy checklist: a stable `BETTER_AUTH_SECRET` and a persistent `DATABASE_URL`, plus `A2A_SECRET` for an app inside a workspace. The skill reports these as the pending step and does not create placeholder values. See [Deploy an app](/docs/deploy-an-app) and [Deploy a workspace](/docs/workspace-deployment).
|
|
102
|
+
|
|
103
|
+
The final report labels evidence separately: locally running, locally verified, build-ready, deployed, and live-verified are different states, and the report never lets one stand in for another.
|
|
104
|
+
|
|
105
|
+
## Known limits {#limits}
|
|
106
|
+
|
|
107
|
+
- **Editing `.env` while the dev server runs.** An in-place reload after an `.env` change loops on the local database lock and serves 500s. Stop the server, edit `.env`, and start it again.
|
|
108
|
+
- **Ambiguous spreadsheets.** If the candidate workflows or the input and output mapping stay materially ambiguous after a bounded review, the skill asks one compact question with its recommended interpretation. In a headless run it prints the question, records the assumption in the brief, and keeps building.
|
|
109
|
+
- **Spreadsheets on a browser host.** A workbook cannot be attached; the host passes a bounded CSV rendering as text, or a URL that is intentionally public, and the handoff says what was left out. A link to a private sheet is not a source; the skill asks for an authenticated Sheets or Drive connection or an export, and never uses a public export URL to get around access controls.
|
|
110
|
+
- **Cell colors.** A text preview cannot prove colors, so on a local host the skill reads both formulas and cached values, and treats color as a weak hint.
|
|
111
|
+
- **Local File Mode apps.** An app whose source of truth is the host's files is local-only and is not deployed.
|
|
112
|
+
- **Browser-host handoffs.** The result is unverified until Dispatch returns a built branch. The skill cannot run or screenshot the app there.
|
|
113
|
+
|
|
114
|
+
## What's next {#whats-next}
|
|
115
|
+
|
|
116
|
+
- [Skills Guide](/docs/skills-guide) for how skills are installed and loaded
|
|
117
|
+
- [Dispatch](/docs/dispatch) for the connector used from Claude and ChatGPT on the web
|
|
118
|
+
- [Deploy an app](/docs/deploy-an-app) for taking the generated app to production
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.204.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": {
|
|
@@ -682,8 +682,8 @@
|
|
|
682
682
|
"yaml": "^2.9.0",
|
|
683
683
|
"yjs": "^13.6.33",
|
|
684
684
|
"zod": "^4.3.6",
|
|
685
|
-
"@agent-native/agentkit": "^0.
|
|
686
|
-
"@agent-native/recap-cli": "^0.5.
|
|
685
|
+
"@agent-native/agentkit": "^0.204.0",
|
|
686
|
+
"@agent-native/recap-cli": "^0.5.66"
|
|
687
687
|
},
|
|
688
688
|
"devDependencies": {
|
|
689
689
|
"@ai-sdk/anthropic": "^3.0.71",
|
|
@@ -753,7 +753,7 @@
|
|
|
753
753
|
"xlsx": "^0.18.5"
|
|
754
754
|
},
|
|
755
755
|
"peerDependencies": {
|
|
756
|
-
"@agent-native/core-corpus": "0.
|
|
756
|
+
"@agent-native/core-corpus": ">=0.196.0",
|
|
757
757
|
"@ai-sdk/anthropic": ">=3",
|
|
758
758
|
"@ai-sdk/cohere": ">=3",
|
|
759
759
|
"@ai-sdk/google": ">=3",
|
|
@@ -16,6 +16,7 @@ Rules:
|
|
|
16
16
|
- To override the inference on an unusual action (e.g. a `POST` that only reads), pass `readOnly: true` on the action definition.
|
|
17
17
|
- To let a mutating action run concurrently with other same-turn tool calls, pass `parallelSafe: true`. Only do this when the action is internally concurrency-safe and order-independent (for example, it uses an app-level lock or idempotent upsert semantics). Mutating actions remain serialized by default.
|
|
18
18
|
- If a successful call hands control to the user — it renders a question, an intake form, or anything else the turn must wait on — pass `endsTurn: true` and make it the first or only call in the turn. It stops subsequent model steps and later calls, but cannot undo calls emitted before it. Without it a completion guard sees a turn that legitimately paused as one that failed to finish. `endsTurn: true` also hides the action from MCP, WebMCP, and A2A callers by default (`isActionExposedToExternalAgents` in core `action.ts`) — an external host has no in-app chat to receive the answer on. Pass `mcpTool: true` alongside it only when an external caller can complete the same operation without that answer.
|
|
19
|
+
- MCP hosts read tool annotations to decide how carefully to treat a call. Every MCP catalog advertises declared `mcpAnnotations` (`readOnlyHint`, `destructiveHint`, `openWorldHint`, optional `idempotentHint`); otherwise `/mcp` derives only `readOnlyHint` and an approval-based `destructiveHint`. Declare them on any external write that removes, overwrites, or replaces user content — recoverable Trash included — and mark idempotency-key-guarded writes `idempotentHint: true`.
|
|
19
20
|
|
|
20
21
|
Agents do NOT need to call `refresh-screen` after a normal action — it's already handled. `refresh-screen` is only needed when the agent mutates data via a path the framework can't see (e.g. writing to an external system the app mirrors) or when the agent wants to pass a `scope` hint for narrower invalidation.
|
|
21
22
|
|
|
@@ -16,6 +16,7 @@ Rules:
|
|
|
16
16
|
- To override the inference on an unusual action (e.g. a `POST` that only reads), pass `readOnly: true` on the action definition.
|
|
17
17
|
- To let a mutating action run concurrently with other same-turn tool calls, pass `parallelSafe: true`. Only do this when the action is internally concurrency-safe and order-independent (for example, it uses an app-level lock or idempotent upsert semantics). Mutating actions remain serialized by default.
|
|
18
18
|
- If a successful call hands control to the user — it renders a question, an intake form, or anything else the turn must wait on — pass `endsTurn: true` and make it the first or only call in the turn. It stops subsequent model steps and later calls, but cannot undo calls emitted before it. Without it a completion guard sees a turn that legitimately paused as one that failed to finish. `endsTurn: true` also hides the action from MCP, WebMCP, and A2A callers by default (`isActionExposedToExternalAgents` in core `action.ts`) — an external host has no in-app chat to receive the answer on. Pass `mcpTool: true` alongside it only when an external caller can complete the same operation without that answer.
|
|
19
|
+
- MCP hosts read tool annotations to decide how carefully to treat a call. Every MCP catalog advertises declared `mcpAnnotations` (`readOnlyHint`, `destructiveHint`, `openWorldHint`, optional `idempotentHint`); otherwise `/mcp` derives only `readOnlyHint` and an approval-based `destructiveHint`. Declare them on any external write that removes, overwrites, or replaces user content — recoverable Trash included — and mark idempotency-key-guarded writes `idempotentHint: true`.
|
|
19
20
|
|
|
20
21
|
Agents do NOT need to call `refresh-screen` after a normal action — it's already handled. `refresh-screen` is only needed when the agent mutates data via a path the framework can't see (e.g. writing to an external system the app mirrors) or when the agent wants to pass a `scope` hint for narrower invalidation.
|
|
21
22
|
|
|
@@ -21,8 +21,10 @@ Four phases, in order. Phase 0 comes before any investigation, not after.
|
|
|
21
21
|
2. **Fix** what the evidence actually proves, at the owning boundary.
|
|
22
22
|
3. **Reply**, under a hard question budget, then recap.
|
|
23
23
|
|
|
24
|
-
Output is fixes
|
|
25
|
-
|
|
24
|
+
Output is fixes. Reply in-thread for every workflow reaction added this run;
|
|
25
|
+
continuing work gets a concrete progress reply, and resolved work gets a final
|
|
26
|
+
reply after verification. Follow
|
|
27
|
+
[`slack-reaction-replies.md`](references/slack-reaction-replies.md).
|
|
26
28
|
|
|
27
29
|
## Slack channels
|
|
28
30
|
|
|
@@ -46,9 +48,10 @@ work, post one status reply with task link and remaining scope.
|
|
|
46
48
|
|
|
47
49
|
## Phase 0: claim what you are taking
|
|
48
50
|
|
|
49
|
-
For an eligible item
|
|
50
|
-
never remove it. Do not resume items excluded by
|
|
51
|
-
**In progress** only when work continues beyond
|
|
51
|
+
Resolve known duplicate clusters before claiming. For an eligible item, add
|
|
52
|
+
`👀` before investigation and never remove it. Do not resume items excluded by
|
|
53
|
+
the Slack ownership gate. Post **In progress** only when work continues beyond
|
|
54
|
+
this run.
|
|
52
55
|
|
|
53
56
|
**Defects are in scope: fix them or ask for the one detail needed to fix them.**
|
|
54
57
|
Investigate first; ask what they saw or did in plain language. Gather request
|
|
@@ -62,13 +65,16 @@ doesn't close a separate defect. Tie each reaction to the scope it marks.
|
|
|
62
65
|
|
|
63
66
|
### Reaction gate
|
|
64
67
|
|
|
65
|
-
`👀` is claim history; `✅` requires **Fixed** after
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
`👀` is claim history; `✅` requires **Fixed** after Phase 2 bars. Check each
|
|
69
|
+
reported symptom separately. For partial fixes, pair `✅` for verified scope
|
|
70
|
+
with `🎫` for any distinct unfinished scope that needs a human to take
|
|
71
|
+
ownership or act, whether or not a ticket exists. Link a verified ticket and
|
|
72
|
+
name its owner/action; without one, keep the handoff explicit in the reply and
|
|
73
|
+
ledger and say that an owner or ticket still needs to be assigned. Do not
|
|
74
|
+
create or promise a ticket without authorization. No `🎫` for fixed scope,
|
|
75
|
+
routine rollout, optional checks, subjective/out-of-scope, or unapproved work.
|
|
76
|
+
**Shipped**/**Live verified** alone don't earn `✅`. Never remove reactions.
|
|
77
|
+
Follow the reply reference before marking an item replied.
|
|
72
78
|
|
|
73
79
|
For every concrete objective defect, attempt to reproduce it before recording
|
|
74
80
|
an evidence limit or asking the reporter for more information. A screenshot,
|
|
@@ -89,7 +95,8 @@ means you found neither a fix nor a useful question; state why in the thread.
|
|
|
89
95
|
For eligible items, use one disposition per row; record it in the recap and, if
|
|
90
96
|
unstated, in the thread or linked work. Do not inspect gated items for status.
|
|
91
97
|
For clusters, post one owner status with each source permalink and
|
|
92
|
-
**Clustered**;
|
|
98
|
+
**Clustered**; do not mark duplicate non-owners separately. Give a distinct
|
|
99
|
+
question or update its own reaction and reply.
|
|
93
100
|
|
|
94
101
|
- **Terminal (keep this workflow's eye):** **Fixed**, **Shipped**, **Live
|
|
95
102
|
verified**, **Open - no question**, **Resolved elsewhere**, **Skipped**,
|
|
@@ -455,16 +462,8 @@ Share only new or useful information.
|
|
|
455
462
|
|
|
456
463
|
### After a PR merges
|
|
457
464
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
For beta app fixes, check the merge-triggered publisher run before giving the
|
|
461
|
-
normal few-hours ETA. This checks release-job status, not beta behavior. If it
|
|
462
|
-
succeeds, say what changed and that it'll be on beta in the next few hours.
|
|
463
|
-
Keep test environment, verification, publisher results, and rollout details out
|
|
464
|
-
of the reply; record evidence in the recap or PR. If the run is missing or
|
|
465
|
-
failed, omit the ETA and state what's done, the exact remaining action and owner,
|
|
466
|
-
and an existing ticket when available. Apply the Reaction gate before `🎫`.
|
|
467
|
-
For packages, state availability without verification details.
|
|
465
|
+
Follow [`slack-reaction-replies.md`](references/slack-reaction-replies.md) for
|
|
466
|
+
post-merge beta ETAs and package replies.
|
|
468
467
|
|
|
469
468
|
For a fixed behavior with a ticketed handoff, state the done behavior and
|
|
470
469
|
remaining action/owner/ticket separately; don't imply the fixed scope is open.
|
|
@@ -561,9 +560,9 @@ Questions asked: N/3 · Dropped at 4 days: N
|
|
|
561
560
|
Repeats of a prior Fixed claim: N (each with its earlier thread and failed fix)
|
|
562
561
|
Upvoted items in scope: N (built: N)
|
|
563
562
|
|
|
564
|
-
| Tracker/source or workflow run | Reporter/owner | Status | Repro or failed step | Pre/post/recovery | Run/SHA/target/version/artifact/runtime proof | Locales | Handoff (action/owner/ticket) |
|
|
563
|
+
| Tracker/source or workflow run | Reporter/owner | Status | Repro or failed step | Pre/post/recovery | Run/SHA/target/version/artifact/runtime proof | Locales | Handoff (action/owner/ticket) | Reply proof | Reactions |
|
|
565
564
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
566
|
-
| 18 / [thread](...) or [workflow run](...) | ... | <disposition> | steps; expected/actual or failed job/step | before/after/recovery run | source/tests/build/run/SHA/target/version/URL | updated/N/A/pending | none or action/owner/[ticket](...) |
|
|
565
|
+
| 18 / [thread](...) or [workflow run](...) | ... | <disposition> | steps; expected/actual or failed job/step | before/after/recovery run | source/tests/build/run/SHA/target/version/URL | updated/N/A/pending | none or action/owner/[ticket](...) | [reply](...) or blocker | 👀 claim; ✅ Fixed; 🎫 human handoff needed |
|
|
567
566
|
|
|
568
567
|
Sibling sweep: <fingerprint> - N hits, M fixed, K triaged
|
|
569
568
|
Tracker: <sheet/export and bounded range> - N rows enumerated, N ledgers complete
|