@agent-native/core 0.79.12 → 0.79.15
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +19 -0
- package/corpus/core/docs/content/locales/zh-TW/a2a-protocol.md +68 -68
- package/corpus/core/docs/content/locales/zh-TW/actions.md +82 -82
- package/corpus/core/docs/content/locales/zh-TW/agent-mentions.md +22 -22
- package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.md +82 -82
- package/corpus/core/docs/content/locales/zh-TW/agent-teams.md +29 -29
- package/corpus/core/docs/content/locales/zh-TW/agent-web-surfaces.md +11 -11
- package/corpus/core/docs/content/locales/zh-TW/audit-log.md +16 -16
- package/corpus/core/docs/content/locales/zh-TW/authentication.md +32 -32
- package/corpus/core/docs/content/locales/zh-TW/automations.md +32 -32
- package/corpus/core/docs/content/locales/zh-TW/blueprint-installer.md +19 -19
- package/corpus/core/docs/content/locales/zh-TW/cli-adapters.md +17 -17
- package/corpus/core/docs/content/locales/zh-TW/client.md +62 -62
- package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.md +32 -32
- package/corpus/core/docs/content/locales/zh-TW/code-agents-ui.md +91 -91
- package/corpus/core/docs/content/locales/zh-TW/components.md +51 -51
- package/corpus/core/docs/content/locales/zh-TW/context-awareness.md +66 -66
- package/corpus/core/docs/content/locales/zh-TW/creating-templates.md +39 -39
- package/corpus/core/docs/content/locales/zh-TW/cross-app-sso.md +29 -29
- package/corpus/core/docs/content/locales/zh-TW/database.md +21 -21
- package/corpus/core/docs/content/locales/zh-TW/deployment.md +37 -37
- package/corpus/core/docs/content/locales/zh-TW/dispatch.md +43 -43
- package/corpus/core/docs/content/locales/zh-TW/drop-in-agent.md +34 -34
- package/corpus/core/docs/content/locales/zh-TW/durable-resume.md +18 -18
- package/corpus/core/docs/content/locales/zh-TW/embedding-sdk.md +73 -73
- package/corpus/core/docs/content/locales/zh-TW/evals.md +16 -16
- package/corpus/core/docs/content/locales/zh-TW/extensions.md +81 -81
- package/corpus/core/docs/content/locales/zh-TW/external-agents.md +146 -146
- package/corpus/core/docs/content/locales/zh-TW/faq.md +43 -43
- package/corpus/core/docs/content/locales/zh-TW/file-uploads.md +11 -11
- package/corpus/core/docs/content/locales/zh-TW/frames.md +33 -33
- package/corpus/core/docs/content/locales/zh-TW/getting-started.md +28 -28
- package/corpus/core/docs/content/locales/zh-TW/harness-agents.md +78 -78
- package/corpus/core/docs/content/locales/zh-TW/human-approval.md +27 -27
- package/corpus/core/docs/content/locales/zh-TW/internationalization.md +19 -19
- package/corpus/core/docs/content/locales/zh-TW/key-concepts.md +68 -68
- package/corpus/core/docs/content/locales/zh-TW/local-file-mode.md +50 -50
- package/corpus/core/docs/content/locales/zh-TW/mcp-apps.md +38 -38
- package/corpus/core/docs/content/locales/zh-TW/mcp-clients.md +67 -67
- package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.md +50 -50
- package/corpus/core/docs/content/locales/zh-TW/messaging.md +99 -99
- package/corpus/core/docs/content/locales/zh-TW/migration-workbench.md +6 -6
- package/corpus/core/docs/content/locales/zh-TW/multi-app-workspace.md +39 -39
- package/corpus/core/docs/content/locales/zh-TW/multi-tenancy.md +7 -7
- package/corpus/core/docs/content/locales/zh-TW/native-chat-ui.md +38 -38
- package/corpus/core/docs/content/locales/zh-TW/notifications.md +23 -23
- package/corpus/core/docs/content/locales/zh-TW/observability.md +49 -49
- package/corpus/core/docs/content/locales/zh-TW/observational-memory.md +23 -23
- package/corpus/core/docs/content/locales/zh-TW/onboarding.md +40 -40
- package/corpus/core/docs/content/locales/zh-TW/plan-plugin.md +37 -37
- package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.md +72 -72
- package/corpus/core/docs/content/locales/zh-TW/processors.md +17 -17
- package/corpus/core/docs/content/locales/zh-TW/progress.md +15 -15
- package/corpus/core/docs/content/locales/zh-TW/pure-agent-apps.md +10 -10
- package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.md +103 -103
- package/corpus/core/docs/content/locales/zh-TW/recurring-jobs.md +19 -19
- package/corpus/core/docs/content/locales/zh-TW/routing.md +9 -9
- package/corpus/core/docs/content/locales/zh-TW/sandbox-adapters.md +48 -48
- package/corpus/core/docs/content/locales/zh-TW/security.md +49 -49
- package/corpus/core/docs/content/locales/zh-TW/server.md +47 -47
- package/corpus/core/docs/content/locales/zh-TW/sharing.md +22 -22
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.md +46 -46
- package/corpus/core/docs/content/locales/zh-TW/template-analytics.md +40 -40
- package/corpus/core/docs/content/locales/zh-TW/template-assets.md +69 -69
- package/corpus/core/docs/content/locales/zh-TW/template-brain.md +81 -81
- package/corpus/core/docs/content/locales/zh-TW/template-calendar.md +40 -40
- package/corpus/core/docs/content/locales/zh-TW/template-chat.md +27 -27
- package/corpus/core/docs/content/locales/zh-TW/template-clips.md +85 -85
- package/corpus/core/docs/content/locales/zh-TW/template-content.md +65 -66
- package/corpus/core/docs/content/locales/zh-TW/template-design.md +29 -29
- package/corpus/core/docs/content/locales/zh-TW/template-dispatch.md +51 -51
- package/corpus/core/docs/content/locales/zh-TW/template-forms.md +25 -25
- package/corpus/core/docs/content/locales/zh-TW/template-mail.md +71 -71
- package/corpus/core/docs/content/locales/zh-TW/template-plan.md +92 -92
- package/corpus/core/docs/content/locales/zh-TW/template-slides.md +52 -52
- package/corpus/core/docs/content/locales/zh-TW/template-videos.md +30 -30
- package/corpus/core/docs/content/locales/zh-TW/tracking.md +29 -29
- package/corpus/core/docs/content/locales/zh-TW/using-your-agent.md +18 -18
- package/corpus/core/docs/content/locales/zh-TW/voice-input.md +19 -19
- package/corpus/core/docs/content/locales/zh-TW/what-is-agent-native.md +61 -61
- package/corpus/core/docs/content/locales/zh-TW/workspace-connections.md +41 -41
- package/corpus/core/docs/content/locales/zh-TW/workspace-management.md +27 -27
- package/corpus/core/docs/content/locales/zh-TW/workspace.md +58 -58
- package/corpus/core/docs/content/locales/zh-TW/writing-agent-instructions.md +41 -41
- package/corpus/core/docs/content/template-clips.md +48 -2
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/client/AgentPanel.tsx +27 -3
- package/corpus/core/src/deploy/build.ts +417 -42
- package/corpus/core/src/deploy/route-discovery.ts +1 -1
- package/corpus/core/src/server/edge.ts +50 -0
- package/corpus/core/src/styles/agent-native.css +93 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +44 -44
- package/corpus/core/src/vite/client.ts +1 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +5 -3
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +69 -70
- package/corpus/templates/analytics/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -3
- package/corpus/templates/assets/app/i18n/zh-TW.ts +82 -82
- package/corpus/templates/assets/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +6 -4
- package/corpus/templates/brain/app/i18n/zh-TW.ts +90 -90
- package/corpus/templates/brain/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +57 -57
- package/corpus/templates/calendar/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/calendar/server/lib/booking-og-fonts.ts +20 -6
- package/corpus/templates/calendar/server/lib/booking-og-image.ts +17 -9
- package/corpus/templates/chat/app/components/layout/Layout.tsx +5 -3
- package/corpus/templates/chat/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/clips/AGENTS.md +6 -0
- package/corpus/templates/clips/actions/delete-recording-permanent.ts +7 -1
- package/corpus/templates/clips/actions/get-recording-player-data.ts +44 -2
- package/corpus/templates/clips/actions/navigate.ts +2 -0
- package/corpus/templates/clips/actions/save-bug-report-context.ts +173 -0
- package/corpus/templates/clips/actions/view-screen.ts +58 -7
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +9 -3
- package/corpus/templates/clips/app/hooks/use-navigation-state.ts +17 -0
- package/corpus/templates/clips/app/i18n/ar-SA.ts +31 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +32 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +32 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +32 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +32 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +32 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +31 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +32 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +32 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +30 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +461 -451
- package/corpus/templates/clips/app/routes/bug-report.done.tsx +126 -0
- package/corpus/templates/clips/app/routes/bug-report.tsx +222 -0
- package/corpus/templates/clips/app/routes/record.tsx +104 -12
- package/corpus/templates/clips/changelog/2026-06-26-brief-network-blips-no-longer-block-recording-or-wrongly-pro.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-bug-report-recordings-can-keep-redacted-host-app-context-wit.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-bug-report-widgets-can-launch-clips-recordings-from-embedded.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-desktop-recording-keeps-connected-users-out-of-the-storage-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-if-a-recording-can-t-be-uploaded-the-chrome-extension-now-sa.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +9 -2
- package/corpus/templates/clips/chrome-extension/src/background.ts +43 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +111 -6
- package/corpus/templates/clips/chrome-extension/src/popup.ts +18 -7
- package/corpus/templates/clips/desktop/src/app.tsx +53 -19
- package/corpus/templates/clips/server/db/schema.ts +26 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +51 -0
- package/corpus/templates/clips/server/plugins/auth.ts +1 -0
- package/corpus/templates/clips/server/plugins/db.ts +28 -0
- package/corpus/templates/clips/server/routes/api/agent-context.json.get.ts +4 -1
- package/corpus/templates/clips/shared/bug-report.ts +161 -0
- package/corpus/templates/content/app/components/layout/Layout.tsx +10 -8
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
- package/corpus/templates/content/app/i18n/zh-TW.ts +67 -66
- package/corpus/templates/content/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +3 -3
- package/corpus/templates/design/app/i18n/zh-TW.ts +44 -44
- package/corpus/templates/design/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/dispatch/app/i18n/zh-TW.ts +5 -4
- package/corpus/templates/dispatch/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/forms/app/components/layout/Layout.tsx +4 -2
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/forms/app/i18n/zh-TW.ts +48 -48
- package/corpus/templates/forms/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +3 -3
- package/corpus/templates/macros/app/i18n/zh-TW.ts +5 -5
- package/corpus/templates/macros/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/mail/app/i18n/zh-TW.ts +83 -83
- package/corpus/templates/mail/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -3
- package/corpus/templates/plan/app/i18n/zh-TW.ts +69 -69
- package/corpus/templates/plan/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -3
- package/corpus/templates/slides/app/i18n/zh-TW.ts +64 -64
- package/corpus/templates/slides/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/templates/videos/app/components/layout/Layout.tsx +2 -2
- package/corpus/templates/videos/app/i18n/zh-TW.ts +54 -54
- package/corpus/templates/videos/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +14 -4
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +3 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +361 -37
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +1 -1
- package/dist/deploy/route-discovery.js +1 -1
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/edge.d.ts +11 -0
- package/dist/server/edge.d.ts.map +1 -0
- package/dist/server/edge.js +11 -0
- package/dist/server/edge.js.map +1 -0
- package/dist/styles/agent-native.css +93 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +44 -44
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/locales/zh-TW/a2a-protocol.md +68 -68
- package/docs/content/locales/zh-TW/actions.md +82 -82
- package/docs/content/locales/zh-TW/agent-mentions.md +22 -22
- package/docs/content/locales/zh-TW/agent-surfaces.md +82 -82
- package/docs/content/locales/zh-TW/agent-teams.md +29 -29
- package/docs/content/locales/zh-TW/agent-web-surfaces.md +11 -11
- package/docs/content/locales/zh-TW/audit-log.md +16 -16
- package/docs/content/locales/zh-TW/authentication.md +32 -32
- package/docs/content/locales/zh-TW/automations.md +32 -32
- package/docs/content/locales/zh-TW/blueprint-installer.md +19 -19
- package/docs/content/locales/zh-TW/cli-adapters.md +17 -17
- package/docs/content/locales/zh-TW/client.md +62 -62
- package/docs/content/locales/zh-TW/cloneable-saas.md +32 -32
- package/docs/content/locales/zh-TW/code-agents-ui.md +91 -91
- package/docs/content/locales/zh-TW/components.md +51 -51
- package/docs/content/locales/zh-TW/context-awareness.md +66 -66
- package/docs/content/locales/zh-TW/creating-templates.md +39 -39
- package/docs/content/locales/zh-TW/cross-app-sso.md +29 -29
- package/docs/content/locales/zh-TW/database.md +21 -21
- package/docs/content/locales/zh-TW/deployment.md +37 -37
- package/docs/content/locales/zh-TW/dispatch.md +43 -43
- package/docs/content/locales/zh-TW/drop-in-agent.md +34 -34
- package/docs/content/locales/zh-TW/durable-resume.md +18 -18
- package/docs/content/locales/zh-TW/embedding-sdk.md +73 -73
- package/docs/content/locales/zh-TW/evals.md +16 -16
- package/docs/content/locales/zh-TW/extensions.md +81 -81
- package/docs/content/locales/zh-TW/external-agents.md +146 -146
- package/docs/content/locales/zh-TW/faq.md +43 -43
- package/docs/content/locales/zh-TW/file-uploads.md +11 -11
- package/docs/content/locales/zh-TW/frames.md +33 -33
- package/docs/content/locales/zh-TW/getting-started.md +28 -28
- package/docs/content/locales/zh-TW/harness-agents.md +78 -78
- package/docs/content/locales/zh-TW/human-approval.md +27 -27
- package/docs/content/locales/zh-TW/internationalization.md +19 -19
- package/docs/content/locales/zh-TW/key-concepts.md +68 -68
- package/docs/content/locales/zh-TW/local-file-mode.md +50 -50
- package/docs/content/locales/zh-TW/mcp-apps.md +38 -38
- package/docs/content/locales/zh-TW/mcp-clients.md +67 -67
- package/docs/content/locales/zh-TW/mcp-protocol.md +50 -50
- package/docs/content/locales/zh-TW/messaging.md +99 -99
- package/docs/content/locales/zh-TW/migration-workbench.md +6 -6
- package/docs/content/locales/zh-TW/multi-app-workspace.md +39 -39
- package/docs/content/locales/zh-TW/multi-tenancy.md +7 -7
- package/docs/content/locales/zh-TW/native-chat-ui.md +38 -38
- package/docs/content/locales/zh-TW/notifications.md +23 -23
- package/docs/content/locales/zh-TW/observability.md +49 -49
- package/docs/content/locales/zh-TW/observational-memory.md +23 -23
- package/docs/content/locales/zh-TW/onboarding.md +40 -40
- package/docs/content/locales/zh-TW/plan-plugin.md +37 -37
- package/docs/content/locales/zh-TW/pr-visual-recap.md +72 -72
- package/docs/content/locales/zh-TW/processors.md +17 -17
- package/docs/content/locales/zh-TW/progress.md +15 -15
- package/docs/content/locales/zh-TW/pure-agent-apps.md +10 -10
- package/docs/content/locales/zh-TW/real-time-collaboration.md +103 -103
- package/docs/content/locales/zh-TW/recurring-jobs.md +19 -19
- package/docs/content/locales/zh-TW/routing.md +9 -9
- package/docs/content/locales/zh-TW/sandbox-adapters.md +48 -48
- package/docs/content/locales/zh-TW/security.md +49 -49
- package/docs/content/locales/zh-TW/server.md +47 -47
- package/docs/content/locales/zh-TW/sharing.md +22 -22
- package/docs/content/locales/zh-TW/skills-guide.md +46 -46
- package/docs/content/locales/zh-TW/template-analytics.md +40 -40
- package/docs/content/locales/zh-TW/template-assets.md +69 -69
- package/docs/content/locales/zh-TW/template-brain.md +81 -81
- package/docs/content/locales/zh-TW/template-calendar.md +40 -40
- package/docs/content/locales/zh-TW/template-chat.md +27 -27
- package/docs/content/locales/zh-TW/template-clips.md +85 -85
- package/docs/content/locales/zh-TW/template-content.md +65 -66
- package/docs/content/locales/zh-TW/template-design.md +29 -29
- package/docs/content/locales/zh-TW/template-dispatch.md +51 -51
- package/docs/content/locales/zh-TW/template-forms.md +25 -25
- package/docs/content/locales/zh-TW/template-mail.md +71 -71
- package/docs/content/locales/zh-TW/template-plan.md +92 -92
- package/docs/content/locales/zh-TW/template-slides.md +52 -52
- package/docs/content/locales/zh-TW/template-videos.md +30 -30
- package/docs/content/locales/zh-TW/tracking.md +29 -29
- package/docs/content/locales/zh-TW/using-your-agent.md +18 -18
- package/docs/content/locales/zh-TW/voice-input.md +19 -19
- package/docs/content/locales/zh-TW/what-is-agent-native.md +61 -61
- package/docs/content/locales/zh-TW/workspace-connections.md +41 -41
- package/docs/content/locales/zh-TW/workspace-management.md +27 -27
- package/docs/content/locales/zh-TW/workspace.md +58 -58
- package/docs/content/locales/zh-TW/writing-agent-instructions.md +41 -41
- package/docs/content/template-clips.md +48 -2
- package/package.json +2 -1
- package/src/templates/default/app/i18n/zh-TW.ts +44 -44
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "路由"
|
|
3
|
-
description: "使用 React Router v8
|
|
3
|
+
description: "使用 React Router v8 為 Agent-Native 應用程式提供基於檔案的路由 - 頁面、動態參數和導覽。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 路由
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Agent-Native 應用程式使用 **React Router v8** 以及透過來自 `@react-router/fs-routes` 的 `flatRoutes()` 的基於檔案的路由。 `app/routes/` 中的每個檔案都會變成 URL。範本使用點符號約定 - 點在單一檔名內分隔 URL 段。
|
|
9
9
|
|
|
10
10
|
## 基於檔案的路由 {#file-based-routing}
|
|
11
11
|
|
|
12
|
-
### 檔案→URL對應
|
|
12
|
+
### 檔案→URL 對應
|
|
13
13
|
|
|
14
|
-
| 檔案 | URL |
|
|
14
|
+
| 檔案 | URL | 註解 |
|
|
15
15
|
| --------------------- | ------------------ | ----------------------------- |
|
|
16
|
-
| `_index.tsx` | `/` |
|
|
16
|
+
| `_index.tsx` | `/` | 索引路由 |
|
|
17
17
|
| `settings.tsx` | `/settings` | 簡單頁面 |
|
|
18
18
|
| `inbox.$threadId.tsx` | `/inbox/:threadId` | 點 = `/`,`$` = 動態參數 |
|
|
19
19
|
| `_app.tsx` | (無 URL 段) | 無路徑布局 - 前綴為 `_` |
|
|
20
20
|
| `inbox/route.tsx` | `/inbox` | 資料夾形式——`route.tsx`為索引 |
|
|
21
21
|
|
|
22
|
-
為動態參數新增 `$` 前綴。以 `_`
|
|
22
|
+
為動態參數新增 `$` 前綴。以 `_` 為前綴,使其成為無路徑布局路由(無 URL 段)。範本使用 `flatRoutes()` — 上面的點符號檔案是主要的;嵌套資料夾形式 `inbox/route.tsx` 也適用。
|
|
23
23
|
|
|
24
24
|
```an-diagram title="無路徑布局包裹頁面" summary="_app.tsx 布局(無 URL 段)渲染共用 shell 一次;匹配的頁面在其 <Outlet/> 內呈現,因此代理側邊欄永遠不會在導覽時重新安裝。"
|
|
25
25
|
{
|
|
@@ -60,7 +60,7 @@ export default function ThreadPage() {
|
|
|
60
60
|
|
|
61
61
|
## 導覽 {#navigation}
|
|
62
62
|
|
|
63
|
-
使用 `<Link>` 進行用戶端導覽,使用 `useNavigate()`
|
|
63
|
+
使用 `<Link>` 進行用戶端導覽,使用 `useNavigate()` 進行程式化導覽:
|
|
64
64
|
|
|
65
65
|
```tsx
|
|
66
66
|
import { Link, useNavigate } from "react-router";
|
|
@@ -73,7 +73,7 @@ const navigate = useNavigate();
|
|
|
73
73
|
navigate(`/inbox/${threadId}`);
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
##
|
|
76
|
+
## 下一步是什麼
|
|
77
77
|
|
|
78
|
-
- [**Client**](/docs/client) -
|
|
78
|
+
- [**Client**](/docs/client) - Agent-Native 瀏覽器掛鉤和實用程式
|
|
79
79
|
- [**Server**](/docs/server) — 基於檔案的伺服器路由和 `/_agent-native/` 命名空間
|
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
description: "
|
|
4
|
-
search: "
|
|
2
|
+
title: "轉接器"
|
|
3
|
+
description: "框架的兩個轉接器接縫:沙箱轉接器交換執行代理執行程式碼工具的後端,CLI 轉接器為代理提供對指令行工具的結構化存取。"
|
|
4
|
+
search: "轉接器沙箱轉接器cli轉接器執行程式碼SandboxAdapter CliAdapter ShellCliAdapter持久執行器遠端沙箱邊緣無伺服器child_process"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# 轉接器
|
|
8
8
|
|
|
9
9
|
> **這是誰的:**擴充功能執行時的主機作者。應用程式開發人員很少
|
|
10
10
|
> 需要這個——預設值開箱即用。
|
|
11
11
|
|
|
12
|
-
Agent-Native
|
|
12
|
+
Agent-Native 有兩個轉接器接縫,可消除狹窄後面的問題,
|
|
13
13
|
可交換介面:
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
- **CLI
|
|
15
|
+
- **沙盒轉接器**交換執行代理的 `run-code` 工具的後端 -
|
|
16
|
+
預設為本機子行程,或 Docker/遠端/持久執行程式。
|
|
17
|
+
- **CLI 轉接器**為代理提供對指令行工具的結構化存取
|
|
18
18
|
(`gh`、`ffmpeg`、`stripe`),具有發現、可用性檢查和
|
|
19
19
|
一致的結果形狀。
|
|
20
20
|
|
|
21
21
|
兩者共用一個執行時約束:它們依賴於 Node.js 系統綁定並執行
|
|
22
|
-
|
|
22
|
+
不在邊緣/工作執行時上執行 - 請參閱 [Edge and serverless](#edge-serverless)。
|
|
23
23
|
|
|
24
24
|
## 我需要哪個編碼檔案? {#which-doc}
|
|
25
25
|
|
|
26
|
-
| 你想要……
|
|
27
|
-
|
|
|
28
|
-
| 交換執行代理 **`run-code` 工具**的後端
|
|
29
|
-
| 封裝一個CLI工具(`gh`、`ffmpeg
|
|
30
|
-
| 渲染 Claude-Code/Codex-style **編碼工作區 UI**
|
|
31
|
-
|
|
|
26
|
+
| 你想要…… | 使用 |
|
|
27
|
+
| ---------------------------------------------------------- | -------------------------------------------- |
|
|
28
|
+
| 交換執行代理 **`run-code` 工具**的後端 | **沙盒轉接器**(本頁面) |
|
|
29
|
+
| 封裝一個 CLI 工具(`gh`、`ffmpeg`)供代理呼叫 | **CLI 轉接器**(本頁面) |
|
|
30
|
+
| 渲染 Claude-Code/Codex-style **編碼工作區 UI** | [Agent-Native Code UI](/docs/code-agents-ui) |
|
|
31
|
+
| 使用自己的迴圈+工具**作為代理**執行 Claude 程式碼/Codex/Pi | [Harness Agents](/docs/harness-agents) |
|
|
32
32
|
|
|
33
|
-
#
|
|
33
|
+
# 沙盒轉接器
|
|
34
34
|
|
|
35
|
-
`run-code` 工具在隔離環境中執行代理提供的 JavaScript。
|
|
35
|
+
`run-code` 工具在隔離環境中執行代理提供的 JavaScript。 **沙箱轉接器**將 _execution_ 問題從該工具中剔除,以便可以交換後端(預設情況下為本機子行程,或 Docker/遠端/持久執行程式),而無需觸及代理迴圈、`run-code.ts`、本機主機橋、環境清理或輸出格式。
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## 為什麼要接縫 {#why}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
預設後端會產生一個鎖定的本機 Node 子行程。這受到託管行程的限制:在託管平台上,它共用代理迴圈的軟執行上限(超時/繼續衝擊之前約 40 秒)。遠端或持久轉接器是超越該上限的杠杆 - 它獨立於請求生命週期執行大型資料作業直至完成。
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
保持契約範圍窄意味著遠端轉接器繼承相同的安全狀態。父行程保留所有秘密的所有權:它建置沙箱模組,執行本機主機橋(它儲存請求脈絡並應用主機允許清單+ SSRF 防護),清理環境並格式化輸出。轉接器僅接收已準備好的、**非秘密**模組來源加上資源限制 - 它僅負責*執行*它並捕獲 stdout/stderr/exit 狀態。
|
|
42
42
|
|
|
43
|
-
```an-diagram title="
|
|
43
|
+
```an-diagram title="父母保守秘密;轉接器僅執行程式碼" summary="run-code 建置模組並執行環回橋;轉接器接收非秘密模組+限制並返回stdout/stderr/exit。"
|
|
44
44
|
{
|
|
45
|
-
"html": "<div class=\"diagram-sandbox\"><div class=\"diagram-box\" data-rough><strong
|
|
45
|
+
"html": "<div class=\"diagram-sandbox\"><div class=\"diagram-box\" data-rough><strong>父行程</strong><small class=\"diagram-muted\">建置模組 · loopback 橋 · 環境清理 · 輸出格式</small></div><div class=\"diagram-col\"><div class=\"diagram-pill accent\">non-secret module + limits →</div><div class=\"diagram-pill ok\">← stdout / stderr / exitCode</div><div class=\"diagram-pill\">↔ bridge calls (127.0.0.1)</div></div><div class=\"diagram-panel center\" data-rough><strong>SandboxAdapter.run</strong><small class=\"diagram-muted\">本機子行程 · Docker · 遠端 · 持久</small></div></div>",
|
|
46
46
|
"css": ".diagram-sandbox{display:flex;align-items:center;gap:14px;flex-wrap:wrap}.diagram-sandbox .diagram-col{display:flex;flex-direction:column;gap:8px}.diagram-sandbox .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## 介面 {#interface}
|
|
51
51
|
|
|
52
|
-
接縫位於 `packages/core/src/coding-tools/sandbox/` 的核心 - `adapter.ts`(合約)、`index.ts`(選取:`getSandboxAdapter()` / `registerSandboxAdapter()`)和 `local-child-process-adapter.ts`(預設)。采用`run-code.ts
|
|
52
|
+
接縫位於 `packages/core/src/coding-tools/sandbox/` 的核心 - `adapter.ts`(合約)、`index.ts`(選取:`getSandboxAdapter()` / `registerSandboxAdapter()`)和 `local-child-process-adapter.ts`(預設)。采用`run-code.ts`封裝內接線;主機透過 `index.ts` 註冊助手插入不同的後端(或者,對於 Docker 後端,透過直接編輯這些檔案的 [blueprint](/docs/blueprint-installer))。
|
|
53
53
|
|
|
54
54
|
```an-file-tree title="core 中的 sandbox 接縫"
|
|
55
55
|
{
|
|
@@ -57,7 +57,7 @@ Agent-Native 有兩個適配器接縫,可消除狹窄後面的問題,
|
|
|
57
57
|
"entries": [
|
|
58
58
|
{ "path": "adapter.ts", "note": "SandboxAdapter 合約(SandboxRunRequest / SandboxRunResult)" },
|
|
59
59
|
{ "path": "index.ts", "note": "選取:getSandboxAdapter() / registerSandboxAdapter()" },
|
|
60
|
-
{ "path": "local-child-process-adapter.ts", "note": "預設後端:受限的 Node
|
|
60
|
+
{ "path": "local-child-process-adapter.ts", "note": "預設後端:受限的 Node 子行程" },
|
|
61
61
|
{ "path": "../run-code.ts", "note": "連線這個接縫;替換 backend 時永遠不變" }
|
|
62
62
|
]
|
|
63
63
|
}
|
|
@@ -111,20 +111,20 @@ interface SandboxRunResult {
|
|
|
111
111
|
|
|
112
112
|
## 預設:`LocalChildProcessAdapter` {#default}
|
|
113
113
|
|
|
114
|
-
開箱即用,`getSandboxAdapter()` 返回 `LocalChildProcessAdapter` (`id: "local-child-process"`)
|
|
114
|
+
開箱即用,`getSandboxAdapter()` 返回 `LocalChildProcessAdapter` (`id: "local-child-process"`)。它逐位元組保留歷史 `run-code` 行為:
|
|
115
115
|
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
- 當節點權限模型可用(節點 20 上的 `--permission` 或 `--experimental-permission
|
|
119
|
-
-
|
|
116
|
+
- 準備好的模組來源被寫入新的臨時目錄。
|
|
117
|
+
- 子行程使用清理後的環境(沒有秘密)執行,`TMPDIR`/`TEMP`/`TMP` 指向沙箱目錄內。
|
|
118
|
+
- 當節點權限模型可用(節點 20 上的 `--permission` 或 `--experimental-permission`)時,子行程將被拒絕存取其臨時目錄之外的檔案系統,以及子行程、工作行程和本機外掛。出站網路不會被權限模型阻止,但環境清理意味著此類請求不攜帶憑證,並且所有經過驗證的呼叫都會透過父級的環回橋。
|
|
119
|
+
- 超時傳送 `SIGTERM`,然後在 2 秒寬限期後傳送 `SIGKILL`。
|
|
120
120
|
- 執行後會盡力清理臨時檔案。
|
|
121
121
|
|
|
122
122
|
> [!WARNING]
|
|
123
|
-
>
|
|
123
|
+
> 預設轉接器使用 `node:child_process`,該轉接器在邊緣/工作執行時上不存在。在標準 Node.js 環境中執行 `run-code`,或註冊遠端轉接器 - 請參閱 [Edge and serverless](#edge-serverless)。
|
|
124
124
|
|
|
125
|
-
##
|
|
125
|
+
## 選取轉接器 {#selection}
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
解決順序——顯式註冊的轉接器獲勝;否則環境變數選取內建的;否則使用本機預設值:
|
|
128
128
|
|
|
129
129
|
```text
|
|
130
130
|
registerSandboxAdapter(adapter) → AGENT_NATIVE_SANDBOX → local default
|
|
@@ -132,7 +132,7 @@ registerSandboxAdapter(adapter) → AGENT_NATIVE_SANDBOX → local default
|
|
|
132
132
|
|
|
133
133
|
### `AGENT_NATIVE_SANDBOX` 環境變數 {#env}
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
透過 id 選取內建轉接器。目前僅有線`local`(預設);未知值回退到本機而不是執行失敗。
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
138
|
AGENT_NATIVE_SANDBOX=local # 預設值——顯式
|
|
@@ -140,7 +140,7 @@ AGENT_NATIVE_SANDBOX=local # 預設值——顯式
|
|
|
140
140
|
|
|
141
141
|
### `registerSandboxAdapter()` {#register}
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
主機行程透過接縫的 `index.ts` 覆蓋所有後續 `run-code` 呼叫的後端 - 例如,執行遠端容器中的每個呼叫:
|
|
144
144
|
|
|
145
145
|
```ts
|
|
146
146
|
import {
|
|
@@ -162,20 +162,20 @@ registerSandboxAdapter(new RemoteSandboxAdapter());
|
|
|
162
162
|
|
|
163
163
|
## 耐用跑鞋的接縫 {#durable}
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
這個介面是特意為未來的遠端/持久沙箱做的接縫。遠端或持久轉接器(Docker、Vercel-Sandbox 式執行程式或排隊背景工作程式)將:
|
|
166
166
|
|
|
167
|
-
1.
|
|
168
|
-
2.
|
|
169
|
-
3. 讓大資料作業獨立於請求生命週期執行直至完成 -
|
|
167
|
+
1. 針對行程外執行時實現 `SandboxAdapter.run`。
|
|
168
|
+
2. 透過隧道環回網橋(或代理網橋回調至父級)。
|
|
169
|
+
3. 讓大資料作業獨立於請求生命週期執行直至完成 - 超過限制本機子行程轉接器的託管約 40 秒程式碼執行上限。
|
|
170
170
|
|
|
171
|
-
將其註冊為新的 `AGENT_NATIVE_SANDBOX` 值(例如 `remote
|
|
171
|
+
將其註冊為新的 `AGENT_NATIVE_SANDBOX` 值(例如 `remote`)和/或透過 `registerSandboxAdapter()`。代理迴圈和 `run-code.ts` 永遠不會改變。
|
|
172
172
|
|
|
173
173
|
> [!TIP]
|
|
174
|
-
> `agent-native add sandbox docker` 藍圖發出了一個完整的、獨立的配方,用於針對此接縫實現 Docker
|
|
174
|
+
> `agent-native add sandbox docker` 藍圖發出了一個完整的、獨立的配方,用於針對此接縫實現 Docker 轉接器。參見[Blueprint Installer](/docs/blueprint-installer)。
|
|
175
175
|
|
|
176
|
-
# CLI
|
|
176
|
+
# CLI 轉接器
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
另一個轉接器接縫包裝單一指令行工具(`gh`、`ffmpeg`、`stripe`、`aws`),以便代理可以發現它,檢查它是否已安裝,並以一致的 stdout/stderr/exit-code 結果執行它。每個 CLI 轉接器都實現 `CliAdapter`:
|
|
179
179
|
|
|
180
180
|
```ts
|
|
181
181
|
import type { CliAdapter, CliResult } from "@agent-native/core/adapters/cli";
|
|
@@ -194,7 +194,7 @@ interface CliResult {
|
|
|
194
194
|
}
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
-
對於大多數 CLI,`ShellCliAdapter` 使用合理的預設值包裝任何二進制檔案,而 `CliRegistry`
|
|
197
|
+
對於大多數 CLI,`ShellCliAdapter` 使用合理的預設值包裝任何二進制檔案,而 `CliRegistry` 收集轉接器以進行執行時發現:
|
|
198
198
|
|
|
199
199
|
```ts
|
|
200
200
|
import { CliRegistry, ShellCliAdapter } from "@agent-native/core/adapters/cli";
|
|
@@ -212,16 +212,16 @@ const gh = cliRegistry.get("gh");
|
|
|
212
212
|
const result = await gh?.execute(["pr", "list", "--json", "title,url"]);
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
將 CLI
|
|
215
|
+
將 CLI 呼叫包裝在 `defineAction` 中以將其公開在操作介面上。請參閱 [CLI Adapters](/docs/cli-adapters) 快速參考,了解 `ShellCliAdapter` 選項、自訂轉接器和操作包裝模式。
|
|
216
216
|
|
|
217
|
-
##
|
|
217
|
+
## 邊緣和無伺服器 {#edge-serverless}
|
|
218
218
|
|
|
219
219
|
> [!WARNING]
|
|
220
|
-
>
|
|
220
|
+
> 兩個轉接器接縫均依賴於 Node.js 系統綁定。沙箱 `LocalChildProcessAdapter` 和 CLI 轉接器(`ShellCliAdapter` 和自訂轉接器)使用 `node:child_process` (`execFile` / `spawn`),這在 Cloudflare Workers 或 Netlify Edge Functions 等邊緣/工作對話串執行時上**不存在**。如果將伺服器路由部署到這些邊緣預設,則執行這些轉接器會引發執行時異常。在標準 Node.js 環境(傳統伺服器容器或無伺服器節點功能)中執行轉接器端點和工作 - 或者,對於沙箱接縫,註冊一個在行程外傳送工作的遠端轉接器。
|
|
221
221
|
|
|
222
|
-
##
|
|
222
|
+
## 下一步是什麼
|
|
223
223
|
|
|
224
224
|
- [**CLI Adapters**](/docs/cli-adapters) — CLI 接縫的快速參考
|
|
225
|
-
- [**Blueprint Installer**](/docs/blueprint-installer) - `agent-native add sandbox docker` 列印 Docker
|
|
225
|
+
- [**Blueprint Installer**](/docs/blueprint-installer) - `agent-native add sandbox docker` 列印 Docker 轉接器配方
|
|
226
226
|
- [**Agent Teams**](/docs/agent-teams) — 將繁重的工作委派給子代理
|
|
227
227
|
- [**Security**](/docs/security) — env 清理和橋允許名單姿勢
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "安全"
|
|
3
|
-
description: "
|
|
3
|
+
description: "Agent-Native 應用的安全模型:輸入驗證、SQL 注入預防、XSS、資料範圍、機密管理和驗證模式。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 安全
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Agent-Native 應用程式預設設計為安全的。此框架提供多層自動保護 - 您可以獲得 SQL 級資料隔離、參數化查詢、輸入驗證和開箱即用的驗證。
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 你免費得到什麼,以及你擁有什麼 {#what-you-own}
|
|
11
11
|
|
|
12
|
-
```an-diagram title="層層防守" summary="
|
|
12
|
+
```an-diagram title="層層防守" summary="此框架擁有大部分威脅面;您擁有兩件事——標記表以確定範圍和驗證外部輸入。"
|
|
13
13
|
{
|
|
14
14
|
"html": "<div class=\"sec-layers\"><div class=\"diagram-card free\"><span class=\"diagram-pill ok\">由框架擁有</span><small class=\"diagram-muted\">SQL isolation · parameterized queries · XSS escaping · auth guard · CSRF cookies · secret encryption</small></div><div class=\"diagram-card you\"><span class=\"diagram-pill warn\">由你掌控</span><small class=\"diagram-muted\">A. tag tables with ownableColumns() & route through access guards<br>B. give every action a Zod schema & send user URLs through the SSRF guard</small></div></div>",
|
|
15
15
|
"css": ".sec-layers{display:flex;flex-direction:column;gap:12px}.sec-layers .diagram-card{display:flex;flex-direction:column;gap:6px;padding:14px 16px}"
|
|
@@ -26,8 +26,8 @@ description: "代理原生應用的安全模型:輸入驗證、SQL 注入預
|
|
|
26
26
|
|
|
27
27
|
這留下了一個你實際上必須考慮的小表面:
|
|
28
28
|
|
|
29
|
-
- **A
|
|
30
|
-
- **B。驗證並路由外部輸入。** 為每個操作指定一個 Zod [`schema:`](#input-validation)
|
|
29
|
+
- **A。標記您的表以進行範圍界定。**透過 [`ownableColumns()`](#data-scoping) 新增 `owner_email`(以及用於團隊資料的 `org_id`),並透過 [access guards](#access-guards) 路由 Drizzle 讀/寫。
|
|
30
|
+
- **B。驗證並路由外部輸入。** 為每個操作指定一個 Zod [`schema:`](#input-validation),並透過 [SSRF guard](#ssrf) 傳送使用者/代理 URL 的任何伺服器端取得。
|
|
31
31
|
|
|
32
32
|
正確設定這兩個,其餘的都是預設值。 [Production Checklist](#production-checklist) 是發貨前的一頁面確認。
|
|
33
33
|
|
|
@@ -37,18 +37,18 @@ description: "代理原生應用的安全模型:輸入驗證、SQL 注入預
|
|
|
37
37
|
|
|
38
38
|
| 漏洞 | 框架保護 |
|
|
39
39
|
| -------- | ------------------------------------------------------------ |
|
|
40
|
-
| SQL注入
|
|
41
|
-
| XSS | React 自動轉義 JSX; TipTap
|
|
42
|
-
|
|
|
40
|
+
| SQL 注入 | `db-query`/`db-exec` 和 Drizzle ORM 中的參數化查詢 |
|
|
41
|
+
| XSS | React 自動轉義 JSX; TipTap 清理富文字 |
|
|
42
|
+
| 資料外洩 | 透過臨時檢視進行 SQL 層級範圍界定(`owner_email`、`org_id`) |
|
|
43
43
|
| 繞過驗證 | Auth Guard 自動保護所有 `defineAction` 端點 |
|
|
44
44
|
| 輸入注入 | `defineAction` 中的 Zod 架構驗證 |
|
|
45
45
|
| CSRF | `SameSite=lax` + `httpOnly` cookie |
|
|
46
46
|
| 秘密曝光 | `.env` gitignored;靜態加密的憑證和保管庫 (AES-256-GCM) |
|
|
47
|
-
| SSRF | `ssrfSafeFetch`
|
|
47
|
+
| SSRF | `ssrfSafeFetch` 阻止內部/中繼資料目標 + 重新導向重新綁定 |
|
|
48
48
|
|
|
49
49
|
## 輸入驗證 {#input-validation}
|
|
50
50
|
|
|
51
|
-
將 `defineAction` 與 Zod `schema:`
|
|
51
|
+
將 `defineAction` 與 Zod `schema:` 一起用於每個操作。此框架會在程式碼執行之前自動驗證輸入:
|
|
52
52
|
|
|
53
53
|
```ts
|
|
54
54
|
import { z } from "zod";
|
|
@@ -86,7 +86,7 @@ await exec(`INSERT INTO notes (title) VALUES ('${title}')`);
|
|
|
86
86
|
```an-callout
|
|
87
87
|
{
|
|
88
88
|
"tone": "risk",
|
|
89
|
-
"body": "
|
|
89
|
+
"body": "切勿透過字串連線或範本文字建置 SQL。將使用者輸入作為 `args` 傳遞到 `exec` / `db-query`,或使用 Drizzle - 兩者都始終參數化。 `pnpm guards` 檢查在 CI 時捕獲無範圍和串聯的查詢。"
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -96,12 +96,12 @@ React 自動轉義所有 JSX 表達式。附加指南:
|
|
|
96
96
|
|
|
97
97
|
- 切勿將 `dangerouslySetInnerHTML` 與使用者控制的內容一起使用
|
|
98
98
|
- 切勿使用 `innerHTML`、`eval()` 或 `document.write()`
|
|
99
|
-
-
|
|
99
|
+
- 對於富文字編輯,請使用 TipTap(框架依賴項)——它透過其架構進行清理
|
|
100
100
|
- 對於渲染 markdown,請使用 `react-markdown` — 它安全地轉換為 React 元素
|
|
101
101
|
|
|
102
|
-
##
|
|
102
|
+
## 伺服器端取得(SSRF) {#ssrf}
|
|
103
103
|
|
|
104
|
-
使用者或代理控制的 URL 的任何伺服器端 `fetch` 都必須經過框架 SSRF
|
|
104
|
+
使用者或代理控制的 URL 的任何伺服器端 `fetch` 都必須經過框架 SSRF 防護,或者它可以指向雲端中繼資料(`169.254.169.254`)、`localhost` 或內部服務:
|
|
105
105
|
|
|
106
106
|
```ts
|
|
107
107
|
import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
|
|
@@ -109,11 +109,11 @@ import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
|
|
|
109
109
|
const res = await ssrfSafeFetch(userProvidedUrl, {}, { maxRedirects: 3 });
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
`ssrfSafeFetch` 阻止私人/內部目標,在連線時重新檢查解析的 IP(DNS 重新綁定),並重新驗證每個重新導向躍點,以便公開 URL 無法重新導向到私人網路。擴充功能 iframe 代理、`upload-image`
|
|
112
|
+
`ssrfSafeFetch` 阻止私人/內部目標,在連線時重新檢查解析的 IP(DNS 重新綁定),並重新驗證每個重新導向躍點,以便公開 URL 無法重新導向到私人網路。擴充功能 iframe 代理、`upload-image` 和設計權杖匯入器都透過它進行路由。對於僅飛行前檢查,請使用 `isBlockedExtensionUrlWithDns(url)` 和 `redirect: "manual"`。
|
|
113
113
|
|
|
114
114
|
## 資料範圍 {#data-scoping}
|
|
115
115
|
|
|
116
|
-
在正式環境中,框架自動將代理 SQL 查詢限制為目前使用者的資料。這是在 SQL
|
|
116
|
+
在正式環境中,框架自動將代理 SQL 查詢限制為目前使用者的資料。這是在 SQL 層級強制執行的——代理無法繞過它。本節是範圍界定管道的規範參考; [Authentication](/docs/authentication) 和 [Multi-Tenancy](/docs/multi-tenancy) 檔案連結位於此處,了解相關機制。
|
|
117
117
|
|
|
118
118
|
### 範圍管道 {#scoping-pipeline}
|
|
119
119
|
|
|
@@ -123,18 +123,18 @@ const res = await ssrfSafeFetch(userProvidedUrl, {}, { maxRedirects: 3 });
|
|
|
123
123
|
session.orgId → AGENT_ORG_ID → SQL row scoping
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
```an-diagram title="範圍界定管道" summary="代理 SQL 從不直接接觸基表 -
|
|
126
|
+
```an-diagram title="範圍界定管道" summary="代理 SQL 從不直接接觸基表 - 它讀取範圍為目前識別的臨時檢視,因此裸表名稱只能返回擁有的行。"
|
|
127
127
|
{
|
|
128
128
|
"html": "<div class=\"scope-pipe\"><div class=\"diagram-node\">已登入工作階段<br><small class=\"diagram-muted\">email · orgId</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-node\">Request context<br><small class=\"diagram-muted\">AGENT_ORG_ID</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-box\">Temporary VIEW<br><small class=\"diagram-muted\">WHERE owner_email = ? AND org_id = ?</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-node ok\">代理 SQL<br><small class=\"diagram-muted\">bare table names only</small></div></div>",
|
|
129
129
|
"css": ".scope-pipe{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.scope-pipe .diagram-node{display:flex;flex-direction:column;gap:2px;padding:10px 14px}.scope-pipe .diagram-arrow{font-size:22px;line-height:1}"
|
|
130
130
|
}
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
登入工作階段攜帶 `email` 和(當組織處於活動狀態時)`orgId
|
|
133
|
+
登入工作階段攜帶 `email` 和(當組織處於活動狀態時)`orgId`。此框架從該工作階段建立請求脈絡,將活動組織暴露給代理 SQL 作為 `AGENT_ORG_ID`,並重寫每個查詢,以便它只能看到目前身分擁有的行。無論查詢來自 UI、操作還是代理,都適用相同的路徑 - 代理無法讀取使用者不是其成員的組織的資料。
|
|
134
134
|
|
|
135
135
|
### 每使用者範圍 (`owner_email`)
|
|
136
136
|
|
|
137
|
-
每個包含使用者特定資料的表**必須**有一個 `owner_email`
|
|
137
|
+
每個包含使用者特定資料的表**必須**有一個 `owner_email` 文字列。使用駝峰命名法 Drizzle 屬性名稱 — `accessFilter` 讀取為 `resourceTable.ownerEmail`:
|
|
138
138
|
|
|
139
139
|
```ts
|
|
140
140
|
import {
|
|
@@ -161,7 +161,7 @@ export const notes = table("notes", {
|
|
|
161
161
|
});
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
此框架建立臨時 SQL 檢視來自動過濾查詢:
|
|
165
165
|
|
|
166
166
|
```sql
|
|
167
167
|
CREATE TEMPORARY VIEW "notes" AS
|
|
@@ -171,13 +171,13 @@ CREATE TEMPORARY VIEW "notes" AS
|
|
|
171
171
|
|
|
172
172
|
當該列尚不存在時,INSERT 語句會自動注入 `owner_email`。
|
|
173
173
|
|
|
174
|
-
`db-query` / `db-exec` 工具拒絕模式限定的表引用(`public.<table>`、`main.<table
|
|
174
|
+
`db-query` / `db-exec` 工具拒絕模式限定的表引用(`public.<table>`、`main.<table>`)——限定名稱解析為基表,並會繞過上面的臨時檢視。代理使用裸表名稱;範圍會自動應用。
|
|
175
175
|
|
|
176
176
|
### 每個組織範圍界定 (`org_id`)
|
|
177
177
|
|
|
178
178
|
對於團隊共用資料的多使用者應用,請新增 `org_id` 列。當兩列都存在時,查詢的範圍為:`WHERE owner_email = ? AND org_id = ?`。
|
|
179
179
|
|
|
180
|
-
`ownableColumns()`
|
|
180
|
+
`ownableColumns()` 架構助手在一次呼叫中新增了 `owner_email`、`org_id` 和 `visibility`,因此新的租戶感知表預設會獲得完整的作用域契約:
|
|
181
181
|
|
|
182
182
|
```ts
|
|
183
183
|
import { table, text, ownableColumns } from "@agent-native/core/db/schema";
|
|
@@ -208,13 +208,13 @@ export const projects = table("projects", {
|
|
|
208
208
|
|
|
209
209
|
### actions中的存取守衛 {#access-guards}
|
|
210
210
|
|
|
211
|
-
原始代理 SQL
|
|
211
|
+
原始代理 SQL 的範圍受上述臨時檢視的限制。直接查詢 Drizzle 的操作的程式碼應透過框架的存取幫助程式,以便讀取和寫入保持在目前身分範圍內:
|
|
212
212
|
|
|
213
|
-
- **`accessFilter`** — 返回 `WHERE`
|
|
213
|
+
- **`accessFilter`** — 返回 `WHERE` 謂詞,該謂詞將查詢限制為目前使用者/組織可能看到的行。在清單/讀取查詢中使用它。
|
|
214
214
|
- **`resolveAccess`** — 解析目前請求的有效存取範圍(所有者、組織、共用)。
|
|
215
|
-
- **`assertAccess`** —
|
|
215
|
+
- **`assertAccess`** — 保護寫入或單紀錄讀取,如果目前識別無法作用於目標行,則拋出異常。
|
|
216
216
|
|
|
217
|
-
使用 `ownableColumns()` 建置的表需要這些範圍內的讀取和寫入;自訂 Nitro
|
|
217
|
+
使用 `ownableColumns()` 建置的表需要這些範圍內的讀取和寫入;自訂 Nitro 路由必須在查詢可擁有資料之前建立請求脈絡。 `guard-no-unscoped-queries` 檢查(透過 `pnpm guards` 執行)在 CI 時強制執行此操作。完整幫手 API 見`sharing`技能。
|
|
218
218
|
|
|
219
219
|
### 驗證
|
|
220
220
|
|
|
@@ -225,17 +225,17 @@ pnpm action db-check-scoping --require-org # 還需要 org_id
|
|
|
225
225
|
|
|
226
226
|
## 秘密管理 {#secrets}
|
|
227
227
|
|
|
228
|
-
| 秘密型別 |
|
|
228
|
+
| 秘密型別 | 儲存位置 |
|
|
229
229
|
| ---------------------------- | -------------------------------------------------- |
|
|
230
230
|
| 部署級金鑰(每個應用一個) | `.env` 檔案(gitignored,僅伺服器端) |
|
|
231
231
|
| 每使用者/每組織 API 金鑰 | `saveCredential` / `resolveCredential`(靜態加密) |
|
|
232
232
|
| 註冊機密(側邊欄保管庫) | `app_secrets`保管庫(靜態加密) |
|
|
233
|
-
| OAuth 代幣(Google、GitHub) | `oauth_tokens`
|
|
233
|
+
| OAuth 代幣(Google、GitHub) | `oauth_tokens` 透過 `saveOAuthTokens()` 儲存 |
|
|
234
234
|
| 工作階段權杖 | 自動(Better Auth 可以處理此問題) |
|
|
235
235
|
|
|
236
236
|
每使用者/每組織憑證和保管庫使用 AES-256-GCM 進行靜態加密,並由 `SECRETS_ENCRYPTION_KEY` 加密(回退到 `BETTER_AUTH_SECRET`);如果沒有一個,正式環境就無法開始。要就地加密任何預先存在的明文憑證行,請執行 `pnpm action db-migrate-encrypt-credentials`(冪等、非破壞性)。
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
切勿將機密儲存在 `settings`、`application_state`、來源程式碼或操作回應中。使用上面的憑證/保險庫 API - 它們處理加密和每使用者範圍。
|
|
239
239
|
|
|
240
240
|
## 驗證 {#auth}
|
|
241
241
|
|
|
@@ -244,28 +244,28 @@ pnpm action db-check-scoping --require-org # 還需要 org_id
|
|
|
244
244
|
**安全要點:**
|
|
245
245
|
|
|
246
246
|
- `defineAction` 端點由驗證防護自動保護
|
|
247
|
-
- 自訂`/api
|
|
247
|
+
- 自訂`/api/`路由必須呼叫`getSession(event)`並檢查結果
|
|
248
248
|
- 狀態更改操作應使用 POST(actions 的預設值)
|
|
249
249
|
- `SameSite=lax` + `httpOnly` cookie 可阻止大多數 CSRF 攻擊
|
|
250
250
|
|
|
251
|
-
## A2A驗證 {#a2a-identity}
|
|
251
|
+
## A2A 驗證 {#a2a-identity}
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
當應用透過 A2A 協議相互呼叫時,它們會使用使用共用金鑰簽名的 JWT 權杖來驗證身分:
|
|
254
254
|
|
|
255
255
|
```bash
|
|
256
256
|
A2A_SECRET=your-shared-secret-at-least-32-chars
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
1. 應用程式A簽署包含`sub: "steve@example.com"`的JWT
|
|
259
|
+
1. 應用程式A簽署包含`sub: "steve@example.com"`的 JWT
|
|
260
260
|
2. 應用程式 B 使用相同的金鑰驗證 JWT 簽名
|
|
261
|
-
3. 應用程式 B 將經過驗證的 `sub`
|
|
261
|
+
3. 應用程式 B 將經過驗證的 `sub` 聲明讀取到請求脈絡中
|
|
262
262
|
4. 資料範圍適用 - 應用程式 B 僅顯示 Steve 的資料
|
|
263
263
|
|
|
264
|
-
如果正式環境中沒有 `A2A_SECRET`,每個 A2A 端點和 `/_agent-native/integrations/process-task` 自觸發端點都會返回 **503
|
|
264
|
+
如果正式環境中沒有 `A2A_SECRET`,每個 A2A 端點和 `/_agent-native/integrations/process-task` 自觸發端點都會返回 **503**。在每個呼叫或接收 A2A 流量的應用程式上設定它。 (對於本機開發,框架仍然允許未經驗證的呼叫。)
|
|
265
265
|
|
|
266
266
|
## 入站Webhooks {#webhooks}
|
|
267
267
|
|
|
268
|
-
入站 webhook
|
|
268
|
+
入站 webhook 處理常式(Resend、SendGrid、Slack、Telegram、WhatsApp、Recall.ai、Deepgram、Zoom、Google Docs Pub/Sub)預設在正式環境中拒絕偽造請求:當缺少相應的簽名秘密環境變數時,處理常式返回 401,而不是接受和分派。
|
|
269
269
|
|
|
270
270
|
這以前是“警告並接受”的立場 - 設定您可能會丟失的秘密,或者選取僅針對本機開發人員使用 `AGENT_NATIVE_ALLOW_UNVERIFIED_WEBHOOKS=1` 恢復舊行為。請參閱 [Messaging](/docs/messaging#env-vars) 了解每個整合簽名秘密變數。
|
|
271
271
|
|
|
@@ -275,22 +275,22 @@ A2A_SECRET=your-shared-secret-at-least-32-chars
|
|
|
275
275
|
|
|
276
276
|
- [ ] `BETTER_AUTH_SECRET` 設定為隨機 32+ 字符字串 (`openssl rand -hex 32`),除非這是從 `A2A_SECRET` 派生的託管工作區部署
|
|
277
277
|
- [ ] `OAUTH_STATE_SECRET` 設定為單獨的隨機 32+ 字符字串(不要重複使用 `BETTER_AUTH_SECRET`) - 請參閱 [OAuth State Signing](#oauth-state)
|
|
278
|
-
- [ ]
|
|
278
|
+
- [ ] 在呼叫或接收 A2A 流量的每個應用程式上設定 `A2A_SECRET` — 請參閱 [A2A Identity Verification](#a2a-identity)
|
|
279
279
|
- [ ] `SECRETS_ENCRYPTION_KEY` 設定(或依賴 `BETTER_AUTH_SECRET` 後備) - 請參閱 [Secrets Management](#secrets)
|
|
280
280
|
- [ ] `AUTH_SKIP_EMAIL_VERIFICATION` 在正式環境中**未**設定(或僅在 QA 預覽部署中設定)
|
|
281
281
|
|
|
282
282
|
### Webhook 秘密(為您使用的整合設定秘密)
|
|
283
283
|
|
|
284
|
-
- [ ] 為每個啟用的入站整合設定簽名金鑰 -
|
|
284
|
+
- [ ] 為每個啟用的入站整合設定簽名金鑰 - 有關每個整合清單,請參閱 [Inbound Webhooks](#webhooks) 和 [Messaging](/docs/messaging#env-vars)
|
|
285
285
|
- [ ] `AGENT_NATIVE_ALLOW_UNVERIFIED_WEBHOOKS` 未在產品中設定
|
|
286
286
|
|
|
287
287
|
### 架構
|
|
288
288
|
|
|
289
289
|
- [ ] 每個面向使用者的表都有 `owner_email`,多使用者表也有 `org_id` — 請參閱 [Data Scoping](#data-scoping)
|
|
290
|
-
- [ ] Ownable-table
|
|
290
|
+
- [ ] Ownable-table 讀/寫透過 [access guards](#access-guards)
|
|
291
291
|
- [ ] 所有 actions 都使用 `defineAction` 和 Zod `schema:` — 參見 [Input Validation](#input-validation)
|
|
292
|
-
- [ ] 使用者/代理 URL
|
|
293
|
-
- [ ] 沒有包含使用者內容的 `dangerouslySetInnerHTML
|
|
292
|
+
- [ ] 使用者/代理 URL 的伺服器端取得透過 `ssrfSafeFetch` — 請參閱 [SSRF](#ssrf)
|
|
293
|
+
- [ ] 沒有包含使用者內容的 `dangerouslySetInnerHTML`(或透過 DOMPurify 執行輸出)
|
|
294
294
|
- [ ] 沒有字串連線 SQL
|
|
295
295
|
- [ ] `pnpm guards` 幹淨(`guard-no-unscoped-queries`、`guard-no-env-credentials`、`guard-no-env-mutation`、`guard-no-localhost-fallback`、`guard-no-unscoped-credentials`、`guard-no-drizzle-push`)
|
|
296
296
|
- [ ] 使用兩個使用者帳戶進行測試以驗證資料隔離
|
|
@@ -299,11 +299,11 @@ A2A_SECRET=your-shared-secret-at-least-32-chars
|
|
|
299
299
|
|
|
300
300
|
- [ ] `AGENT_NATIVE_DEBUG_ERRORS` 在真實產品中**未**設定(僅在偵錯預覽中)
|
|
301
301
|
- [ ] `AGENT_NATIVE_KEYS_WORKSPACE_FALLBACK` **未**設定,除非您的組織實際上共用工作區金鑰 - 請參閱 [Cross-User Tooling Secrets](#tooling-secrets)
|
|
302
|
-
- [] 在多租戶部署中,**使用者自帶 `ANTHROPIC_API_KEY`** -
|
|
302
|
+
- [] 在多租戶部署中,**使用者自帶 `ANTHROPIC_API_KEY`** - 框架拒絕回退到部署層級環境變數
|
|
303
303
|
|
|
304
304
|
---
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
以下部分介紹了您只能在特定部署中使用的利基環境標誌。大多數應用程式從不接觸它們。
|
|
307
307
|
|
|
308
308
|
## OAuth 狀態簽名 {#oauth-state}
|
|
309
309
|
|
|
@@ -313,18 +313,18 @@ OAuth 流(Google、Atlassian、Zoom)使用專用的 HMAC 金鑰簽署其狀
|
|
|
313
313
|
OAUTH_STATE_SECRET=$(openssl rand -hex 32)
|
|
314
314
|
```
|
|
315
315
|
|
|
316
|
-
這曾經退回到 `GOOGLE_CLIENT_SECRET`(與 Google 共用的憑證)——Google
|
|
316
|
+
這曾經退回到 `GOOGLE_CLIENT_SECRET`(與 Google 共用的憑證)——Google 秘密的外洩會讓攻擊者偽造 OAuth 狀態信封。專用金鑰獨立於任何第三方秘密。如果 `OAUTH_STATE_SECRET` 未設定,則框架回退到 `BETTER_AUTH_SECRET`;託管工作區部署還可以從已經需要的 `A2A_SECRET` 派生專用 OAuth 金鑰。如果這些伺服器機密均不可用,OAuth 流程將在正式環境中失敗。
|
|
317
317
|
|
|
318
|
-
`redirect_uri` 查詢參數也會根據允許清單(同來源 + 框架 `/_agent-native/...` 路徑)進行驗證。範本中的自訂 OAuth 流應在簽署狀態之前使用框架的 `isAllowedOAuthRedirectUri()`
|
|
318
|
+
`redirect_uri` 查詢參數也會根據允許清單(同來源 + 框架 `/_agent-native/...` 路徑)進行驗證。範本中的自訂 OAuth 流應在簽署狀態之前使用框架的 `isAllowedOAuthRedirectUri()` 幫助程式。
|
|
319
319
|
|
|
320
320
|
## 跨使用者工具秘密 {#tooling-secrets}
|
|
321
321
|
|
|
322
|
-
預設情況下,引用 `${keys.NAME}` 的工具和自動化會解析每個使用者的機密。在此版本中,工作區範圍回退預設情況下處於關閉狀態 - 惡意組織成員可能會植入工作區 `OPENAI_API_KEY`
|
|
322
|
+
預設情況下,引用 `${keys.NAME}` 的工具和自動化會解析每個使用者的機密。在此版本中,工作區範圍回退預設情況下處於關閉狀態 - 惡意組織成員可能會植入工作區 `OPENAI_API_KEY` 並取得其他成員的 API 呼叫。
|
|
323
323
|
|
|
324
|
-
|
|
324
|
+
如果您的組織真正共用工作區範圍的金鑰(例如單一公司 Stripe 金鑰),請選取恢復舊行為:
|
|
325
325
|
|
|
326
326
|
```bash
|
|
327
327
|
AGENT_NATIVE_KEYS_WORKSPACE_FALLBACK=1
|
|
328
328
|
```
|
|
329
329
|
|
|
330
|
-
|
|
330
|
+
無論此標誌如何,工作空間範圍的秘密寫入仍然需要組織所有者/管理員角色。
|