@agent-native/core 0.147.0 → 0.148.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/analytics/DEVELOPING.md +50 -3
- package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
- package/corpus/templates/analytics/app/i18n/index.ts +14 -29
- package/corpus/templates/analytics/app/i18n-data.ts +10 -10
- package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +197 -18
- package/corpus/templates/analytics/server/db/schema.ts +23 -0
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
- package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
- package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
- package/corpus/templates/analytics/server/plugins/db.ts +42 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/assets/app/i18n/index.ts +14 -29
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/brain/app/i18n/index.ts +14 -29
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/app/i18n/index.ts +14 -29
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
- package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/content/app/i18n/index.ts +14 -29
- package/corpus/templates/crm/app/i18n/index.ts +14 -29
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/design/actions/import-code.ts +2 -43
- package/corpus/templates/design/app/i18n/index.ts +14 -29
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/dispatch/app/i18n-data.ts +1 -1
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/factory/AGENTS.md +40 -49
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
- package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
- package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
- package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
- package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
- package/corpus/templates/factory/app/routes/factory.tsx +95 -42
- package/corpus/templates/factory/server/db/schema.ts +37 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
- package/corpus/templates/factory/server/triage/audit.ts +79 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/forms/app/i18n/index.ts +14 -29
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/macros/app/i18n/index.ts +14 -29
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/mail/app/i18n/index.ts +14 -29
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
- package/corpus/templates/plan/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/slides/actions/import-code.ts +2 -43
- package/corpus/templates/slides/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
- package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
- package/corpus/templates/tasks/app/i18n/index.ts +14 -29
- package/dist/agent/engine/ai-sdk-engine.js +2 -1
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
- package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
- package/dist/agent/engine/provider-endpoint-validation.js +26 -0
- package/dist/agent/engine/provider-env-vars.d.ts +1 -1
- package/dist/agent/engine/provider-env-vars.js +1 -1
- package/dist/agent/engine/registry.d.ts +8 -6
- package/dist/agent/engine/registry.js +37 -24
- package/dist/agent/tool-search.d.ts +1 -0
- package/dist/agent/tool-search.js +17 -1
- package/dist/automations/service.js +4 -10
- package/dist/brand-kit/brand-signals.d.ts +13 -0
- package/dist/brand-kit/brand-signals.js +15 -0
- package/dist/brand-kit/index.d.ts +2 -2
- package/dist/brand-kit/index.js +1 -1
- package/dist/cli/plan-blocks.d.ts +3 -18
- package/dist/cli/plan-blocks.js +2 -95
- package/dist/cli/plan-publish-store.d.ts +2 -61
- package/dist/cli/plan-publish-store.js +2 -127
- package/dist/cli/skills-content/connection.d.ts +1 -1
- package/dist/cli/skills-content/connection.js +1 -52
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +1 -553
- package/dist/client/agent-engine-key.d.ts +14 -4
- package/dist/client/agent-engine-key.js +51 -5
- package/dist/client/agent-provider-catalog.d.ts +20 -0
- package/dist/client/agent-provider-catalog.js +100 -0
- package/dist/client/blocks/index.d.ts +1 -0
- package/dist/client/blocks/index.js +1 -0
- package/dist/client/chat/run-recovery.js +4 -48
- package/dist/client/chat-first.js +4 -3
- package/dist/client/i18n.d.ts +14 -0
- package/dist/client/i18n.js +18 -0
- package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
- package/dist/client/settings/ProviderSetupForm.js +145 -0
- package/dist/client/settings/SettingsPanel.js +52 -49
- package/dist/client/settings/index.d.ts +2 -0
- package/dist/client/settings/index.js +2 -0
- package/dist/coding-tools/run-code.d.ts +5 -0
- package/dist/coding-tools/run-code.js +196 -36
- package/dist/coding-tools/tool-orchestration.d.ts +10 -0
- package/dist/coding-tools/tool-orchestration.js +107 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/jobs/frontmatter.d.ts +9 -0
- package/dist/jobs/frontmatter.js +16 -0
- package/dist/jobs/scheduler.js +8 -8
- package/dist/jobs/tools.d.ts +1 -1
- package/dist/jobs/tools.js +2 -7
- package/dist/localization/default-messages.d.ts +20 -0
- package/dist/localization/default-messages.js +25 -5
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
- package/dist/server/agent-chat/run-code-tools.js +3 -1
- package/dist/server/agent-chat-plugin.js +6 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.js +43 -12
- package/dist/server/agents-bundle.js +2 -1
- package/dist/server/auth.js +21 -5
- package/dist/server/credential-provider.js +1 -0
- package/dist/server/design-token-utils.d.ts +18 -0
- package/dist/server/design-token-utils.js +31 -0
- package/dist/server/onboarding-html.js +22 -2
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/chat/app/i18n/index.ts +14 -29
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/default/app/i18n/index.ts +14 -29
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/triggers/dispatcher.js +1 -8
- package/docs/content/environment-variables.mdx +39 -38
- package/package.json +4 -4
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/chat/app/i18n/index.ts +14 -29
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/default/app/i18n/index.ts +14 -29
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
|
@@ -4,12 +4,8 @@ import {
|
|
|
4
4
|
} from "@agent-native/core/client/api-path";
|
|
5
5
|
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
6
6
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
IconExternalLink,
|
|
10
|
-
IconLoader2,
|
|
11
|
-
IconTrash,
|
|
12
|
-
} from "@tabler/icons-react";
|
|
7
|
+
import { SettingsGroup, SettingsRow } from "@agent-native/core/client/settings";
|
|
8
|
+
import { IconBrandSlack, IconLoader2, IconTrash } from "@tabler/icons-react";
|
|
13
9
|
import { useState } from "react";
|
|
14
10
|
import { toast } from "sonner";
|
|
15
11
|
|
|
@@ -24,13 +20,6 @@ import {
|
|
|
24
20
|
AlertDialogTitle,
|
|
25
21
|
} from "@/components/ui/alert-dialog";
|
|
26
22
|
import { Button } from "@/components/ui/button";
|
|
27
|
-
import {
|
|
28
|
-
Card,
|
|
29
|
-
CardContent,
|
|
30
|
-
CardDescription,
|
|
31
|
-
CardHeader,
|
|
32
|
-
CardTitle,
|
|
33
|
-
} from "@/components/ui/card";
|
|
34
23
|
|
|
35
24
|
interface SlackInstallation {
|
|
36
25
|
id: string;
|
|
@@ -188,103 +177,72 @@ export function SlackSection() {
|
|
|
188
177
|
|
|
189
178
|
return (
|
|
190
179
|
<>
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
? t("
|
|
206
|
-
:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
</div>
|
|
180
|
+
<SettingsGroup
|
|
181
|
+
id="slack"
|
|
182
|
+
title={t("settings.slackTitle")}
|
|
183
|
+
description={t("settings.slackDescription")}
|
|
184
|
+
>
|
|
185
|
+
<SettingsRow
|
|
186
|
+
label={
|
|
187
|
+
slackStatus.isLoading
|
|
188
|
+
? t("settings.checkingSlack")
|
|
189
|
+
: connected
|
|
190
|
+
? t("settings.slackConnected", {
|
|
191
|
+
count: installations.length,
|
|
192
|
+
})
|
|
193
|
+
: oauthConfigured
|
|
194
|
+
? t("common.notConnected")
|
|
195
|
+
: t("settings.slackOauthNeeded")
|
|
196
|
+
}
|
|
197
|
+
description={
|
|
198
|
+
!oauthConfigured
|
|
199
|
+
? t("settings.slackClientMissing")
|
|
200
|
+
: !signingConfigured
|
|
201
|
+
? t("settings.slackSigningMissing")
|
|
202
|
+
: t("settings.slackPreviewDescription")
|
|
203
|
+
}
|
|
204
|
+
icon={<IconBrandSlack className="text-primary" />}
|
|
205
|
+
control={
|
|
218
206
|
<Button
|
|
219
207
|
type="button"
|
|
220
|
-
variant="
|
|
208
|
+
variant="default"
|
|
221
209
|
size="sm"
|
|
222
|
-
className="shrink-0"
|
|
223
210
|
onClick={handleConnect}
|
|
224
211
|
disabled={connecting || slackStatus.isLoading || !oauthConfigured}
|
|
225
212
|
>
|
|
226
|
-
{connecting ?
|
|
227
|
-
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
228
|
-
) : (
|
|
229
|
-
<IconExternalLink className="h-4 w-4" />
|
|
230
|
-
)}
|
|
213
|
+
{connecting ? <IconLoader2 className="animate-spin" /> : null}
|
|
231
214
|
{t("settings.connectSlack")}
|
|
232
215
|
</Button>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
{!oauthConfigured ? (
|
|
236
|
-
<div className="rounded-md border border-border p-3 text-xs text-muted-foreground">
|
|
237
|
-
{t("settings.slackClientMissing")}
|
|
238
|
-
</div>
|
|
239
|
-
) : null}
|
|
240
|
-
|
|
241
|
-
{!signingConfigured ? (
|
|
242
|
-
<div className="rounded-md border border-border p-3 text-xs text-muted-foreground">
|
|
243
|
-
{t("settings.slackSigningMissing")}
|
|
244
|
-
</div>
|
|
245
|
-
) : null}
|
|
216
|
+
}
|
|
217
|
+
/>
|
|
246
218
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
className="shrink-0"
|
|
275
|
-
aria-label={t("settings.disconnectSlackLabel", {
|
|
276
|
-
team: installation.teamName || installation.teamId,
|
|
277
|
-
})}
|
|
278
|
-
onClick={() => setDisconnectTarget(installation)}
|
|
279
|
-
>
|
|
280
|
-
<IconTrash className="h-4 w-4" />
|
|
281
|
-
</Button>
|
|
282
|
-
</div>
|
|
283
|
-
))}
|
|
284
|
-
</div>
|
|
285
|
-
) : null}
|
|
286
|
-
</CardContent>
|
|
287
|
-
</Card>
|
|
219
|
+
{installations.map((installation) => (
|
|
220
|
+
<SettingsRow
|
|
221
|
+
key={installation.id}
|
|
222
|
+
label={installation.teamName || installation.teamId}
|
|
223
|
+
description={[
|
|
224
|
+
installation.status,
|
|
225
|
+
installation.enterpriseName,
|
|
226
|
+
t("settings.connectedBy", { email: installation.ownerEmail }),
|
|
227
|
+
]
|
|
228
|
+
.filter(Boolean)
|
|
229
|
+
.join(" · ")}
|
|
230
|
+
control={
|
|
231
|
+
<Button
|
|
232
|
+
type="button"
|
|
233
|
+
variant="ghost"
|
|
234
|
+
size="icon"
|
|
235
|
+
aria-label={t("settings.disconnectSlackLabel", {
|
|
236
|
+
team: installation.teamName || installation.teamId,
|
|
237
|
+
})}
|
|
238
|
+
onClick={() => setDisconnectTarget(installation)}
|
|
239
|
+
>
|
|
240
|
+
<IconTrash />
|
|
241
|
+
</Button>
|
|
242
|
+
}
|
|
243
|
+
/>
|
|
244
|
+
))}
|
|
245
|
+
</SettingsGroup>
|
|
288
246
|
|
|
289
247
|
<AlertDialog
|
|
290
248
|
open={!!disconnectTarget}
|
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
2
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
IconChevronDown,
|
|
6
|
-
IconCloud,
|
|
7
|
-
IconExternalLink,
|
|
8
|
-
IconKey,
|
|
9
|
-
IconLoader2,
|
|
10
|
-
IconServer,
|
|
11
|
-
IconTrash,
|
|
12
|
-
} from "@tabler/icons-react";
|
|
3
|
+
import { SettingsGroup, SettingsRow } from "@agent-native/core/client/settings";
|
|
4
|
+
import { IconCheck, IconLoader2, IconTrash } from "@tabler/icons-react";
|
|
13
5
|
import { useState } from "react";
|
|
14
6
|
import { toast } from "sonner";
|
|
15
7
|
|
|
16
|
-
import { Badge } from "@/components/ui/badge";
|
|
17
8
|
import { Button } from "@/components/ui/button";
|
|
18
|
-
import {
|
|
19
|
-
Card,
|
|
20
|
-
CardContent,
|
|
21
|
-
CardDescription,
|
|
22
|
-
CardHeader,
|
|
23
|
-
CardTitle,
|
|
24
|
-
} from "@/components/ui/card";
|
|
25
9
|
import {
|
|
26
10
|
Collapsible,
|
|
27
11
|
CollapsibleContent,
|
|
@@ -31,7 +15,6 @@ import { Input } from "@/components/ui/input";
|
|
|
31
15
|
import { Label } from "@/components/ui/label";
|
|
32
16
|
import type { SecretStatus } from "@/hooks/use-secret-status";
|
|
33
17
|
import type { useVideoStorageStatus } from "@/hooks/use-video-storage-status";
|
|
34
|
-
import { cn } from "@/lib/utils";
|
|
35
18
|
|
|
36
19
|
import type { BuilderConnection } from "./types";
|
|
37
20
|
|
|
@@ -232,212 +215,152 @@ export function VideoStorageSection({
|
|
|
232
215
|
}
|
|
233
216
|
|
|
234
217
|
return (
|
|
235
|
-
<
|
|
236
|
-
<
|
|
237
|
-
<
|
|
238
|
-
|
|
239
|
-
{
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
<div className="flex items-center gap-2
|
|
218
|
+
<SettingsGroup id="video-storage" title={t("settings.videoStorage")}>
|
|
219
|
+
<Collapsible open={expanded} onOpenChange={setExpanded}>
|
|
220
|
+
<SettingsRow
|
|
221
|
+
label="Builder.io"
|
|
222
|
+
description={
|
|
223
|
+
builder.loading
|
|
224
|
+
? t("settings.checkingBuilder")
|
|
225
|
+
: s3Configured && storageConfigured && activeProviderName
|
|
226
|
+
? t("settings.s3CurrentProvider", {
|
|
227
|
+
providerName: activeProviderName,
|
|
228
|
+
})
|
|
229
|
+
: builder.connected
|
|
230
|
+
? builder.orgName
|
|
231
|
+
? t("settings.builderConnectedFor", {
|
|
232
|
+
orgName: builder.orgName,
|
|
233
|
+
})
|
|
234
|
+
: t("settings.builderConnectedGeneric")
|
|
235
|
+
: t("settings.builderIncludes")
|
|
236
|
+
}
|
|
237
|
+
control={
|
|
238
|
+
<div className="flex flex-wrap items-center justify-end gap-2">
|
|
256
239
|
{builder.connected ? (
|
|
257
|
-
<
|
|
240
|
+
<span className="inline-flex items-center gap-1.5 text-sm font-medium text-primary">
|
|
241
|
+
<IconCheck className="h-4 w-4" />
|
|
242
|
+
{t("common.connected")}
|
|
243
|
+
</span>
|
|
258
244
|
) : (
|
|
259
|
-
<
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
268
|
-
{builder.connected
|
|
269
|
-
? builder.orgName
|
|
270
|
-
? t("settings.builderConnectedFor", {
|
|
271
|
-
orgName: builder.orgName,
|
|
245
|
+
<Button
|
|
246
|
+
type="button"
|
|
247
|
+
variant="default"
|
|
248
|
+
size="sm"
|
|
249
|
+
onClick={() =>
|
|
250
|
+
builder.start({
|
|
251
|
+
trackingSource: "clips_settings_video_storage",
|
|
252
|
+
trackingFlow: "video_storage",
|
|
272
253
|
})
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
<Badge variant="secondary" className="shrink-0">
|
|
279
|
-
{t("common.connected")}
|
|
280
|
-
</Badge>
|
|
281
|
-
) : (
|
|
282
|
-
<Button
|
|
283
|
-
type="button"
|
|
284
|
-
variant="outline"
|
|
285
|
-
size="sm"
|
|
286
|
-
className="shrink-0"
|
|
287
|
-
onClick={() =>
|
|
288
|
-
builder.start({
|
|
289
|
-
trackingSource: "clips_settings_video_storage",
|
|
290
|
-
trackingFlow: "video_storage",
|
|
291
|
-
})
|
|
292
|
-
}
|
|
293
|
-
disabled={builder.connecting || builder.loading}
|
|
294
|
-
>
|
|
295
|
-
{builder.connecting ? (
|
|
296
|
-
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
297
|
-
) : (
|
|
298
|
-
<IconExternalLink className="h-4 w-4" />
|
|
299
|
-
)}
|
|
300
|
-
{t("settings.connectBuilder")}
|
|
301
|
-
</Button>
|
|
302
|
-
)}
|
|
303
|
-
</div>
|
|
304
|
-
|
|
305
|
-
<Collapsible open={expanded} onOpenChange={setExpanded}>
|
|
306
|
-
<div className="rounded-md border border-border">
|
|
307
|
-
<div className="flex flex-col gap-3 px-3 py-3 sm:flex-row sm:items-center sm:justify-between">
|
|
308
|
-
<div className="min-w-0">
|
|
309
|
-
<div className="flex flex-wrap items-center gap-2 text-sm font-medium">
|
|
310
|
-
<IconServer className="h-4 w-4 text-muted-foreground" />
|
|
311
|
-
{t("settings.s3Title")}
|
|
312
|
-
<Badge variant="outline" className="text-[10px]">
|
|
313
|
-
{t("settings.secondary")}
|
|
314
|
-
</Badge>
|
|
315
|
-
{s3Configured ? (
|
|
316
|
-
<Badge variant="secondary" className="text-[10px]">
|
|
317
|
-
{t("settings.active")}
|
|
318
|
-
</Badge>
|
|
254
|
+
}
|
|
255
|
+
disabled={builder.connecting || builder.loading}
|
|
256
|
+
>
|
|
257
|
+
{builder.connecting ? (
|
|
258
|
+
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
319
259
|
) : null}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
? t("settings.s3BuilderConnectedDescription")
|
|
324
|
-
: storageConfigured && activeProviderName
|
|
325
|
-
? t("settings.s3CurrentProvider", {
|
|
326
|
-
providerName: activeProviderName,
|
|
327
|
-
})
|
|
328
|
-
: t("settings.s3OwnBucketDescription")}
|
|
329
|
-
</p>
|
|
330
|
-
</div>
|
|
260
|
+
{t("settings.connectBuilder")}
|
|
261
|
+
</Button>
|
|
262
|
+
)}
|
|
331
263
|
<CollapsibleTrigger asChild>
|
|
264
|
+
<Button type="button" variant="outline" size="sm">
|
|
265
|
+
{expanded
|
|
266
|
+
? t("settings.hideS3")
|
|
267
|
+
: s3Configured
|
|
268
|
+
? t("settings.providerManage")
|
|
269
|
+
: t("settings.configureS3")}
|
|
270
|
+
</Button>
|
|
271
|
+
</CollapsibleTrigger>
|
|
272
|
+
</div>
|
|
273
|
+
}
|
|
274
|
+
/>
|
|
275
|
+
|
|
276
|
+
<CollapsibleContent>
|
|
277
|
+
<div className="space-y-4 border-t border-border px-5 py-4">
|
|
278
|
+
<div className="grid gap-4 sm:grid-cols-2">
|
|
279
|
+
{S3_STORAGE_FIELDS.map((field) => {
|
|
280
|
+
const configured = Boolean(secrets.configured[field.key]);
|
|
281
|
+
const last4 = secrets.last4[field.key];
|
|
282
|
+
return (
|
|
283
|
+
<div key={field.key} className="space-y-1.5">
|
|
284
|
+
<div className="flex items-center justify-between gap-2">
|
|
285
|
+
<Label htmlFor={field.key}>{t(field.labelKey)}</Label>
|
|
286
|
+
{configured ? (
|
|
287
|
+
<span className="flex items-center gap-1 text-[10px] font-medium text-primary">
|
|
288
|
+
<IconCheck className="h-3 w-3" />
|
|
289
|
+
{last4 ? `••••${last4}` : t("settings.keySet")}
|
|
290
|
+
</span>
|
|
291
|
+
) : null}
|
|
292
|
+
</div>
|
|
293
|
+
<Input
|
|
294
|
+
id={field.key}
|
|
295
|
+
type={
|
|
296
|
+
"secret" in field && field.secret ? "password" : "text"
|
|
297
|
+
}
|
|
298
|
+
value={values[field.key] ?? ""}
|
|
299
|
+
onChange={(event) => {
|
|
300
|
+
setValues((current) => ({
|
|
301
|
+
...current,
|
|
302
|
+
[field.key]: event.target.value,
|
|
303
|
+
}));
|
|
304
|
+
if (errors[field.key]) {
|
|
305
|
+
setErrors((current) => {
|
|
306
|
+
const next = { ...current };
|
|
307
|
+
delete next[field.key];
|
|
308
|
+
return next;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}}
|
|
312
|
+
placeholder={
|
|
313
|
+
configured
|
|
314
|
+
? t("settings.replaceKey")
|
|
315
|
+
: field.placeholder
|
|
316
|
+
}
|
|
317
|
+
autoComplete="off"
|
|
318
|
+
disabled={saving}
|
|
319
|
+
className={
|
|
320
|
+
errors[field.key] ? "border-destructive" : undefined
|
|
321
|
+
}
|
|
322
|
+
/>
|
|
323
|
+
{errors[field.key] ? (
|
|
324
|
+
<p className="text-[11px] text-destructive">
|
|
325
|
+
{errors[field.key]}
|
|
326
|
+
</p>
|
|
327
|
+
) : null}
|
|
328
|
+
</div>
|
|
329
|
+
);
|
|
330
|
+
})}
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<div className="flex items-center justify-end gap-2">
|
|
334
|
+
{S3_STORAGE_FIELDS.some(
|
|
335
|
+
(field) => secrets.configured[field.key],
|
|
336
|
+
) ? (
|
|
332
337
|
<Button
|
|
333
338
|
type="button"
|
|
334
339
|
variant="ghost"
|
|
335
340
|
size="sm"
|
|
336
|
-
|
|
341
|
+
onClick={handleClearAll}
|
|
342
|
+
disabled={clearing || saving}
|
|
343
|
+
className="text-muted-foreground hover:text-destructive"
|
|
337
344
|
>
|
|
338
|
-
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
/>
|
|
345
|
+
{clearing ? (
|
|
346
|
+
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
347
|
+
) : (
|
|
348
|
+
<IconTrash className="h-4 w-4" />
|
|
349
|
+
)}
|
|
350
|
+
{t("settings.clearAllS3")}
|
|
345
351
|
</Button>
|
|
346
|
-
|
|
352
|
+
) : null}
|
|
353
|
+
<Button
|
|
354
|
+
onClick={handleSave}
|
|
355
|
+
disabled={saving || storageStatus.isLoading}
|
|
356
|
+
>
|
|
357
|
+
{saving && <IconLoader2 className="h-4 w-4 animate-spin" />}
|
|
358
|
+
{t("settings.saveStorage")}
|
|
359
|
+
</Button>
|
|
347
360
|
</div>
|
|
348
|
-
|
|
349
|
-
<CollapsibleContent>
|
|
350
|
-
<div className="space-y-4 border-t border-border px-3 py-4">
|
|
351
|
-
<div className="grid gap-4 sm:grid-cols-2">
|
|
352
|
-
{S3_STORAGE_FIELDS.map((field) => {
|
|
353
|
-
const configured = Boolean(secrets.configured[field.key]);
|
|
354
|
-
const last4 = secrets.last4[field.key];
|
|
355
|
-
return (
|
|
356
|
-
<div key={field.key} className="space-y-1.5">
|
|
357
|
-
<div className="flex items-center justify-between gap-2">
|
|
358
|
-
<Label htmlFor={field.key}>{t(field.labelKey)}</Label>
|
|
359
|
-
{configured ? (
|
|
360
|
-
<span className="flex items-center gap-1 text-[10px] font-medium text-primary">
|
|
361
|
-
<IconCheck className="h-3 w-3" />
|
|
362
|
-
{last4 ? `••••${last4}` : t("settings.keySet")}
|
|
363
|
-
</span>
|
|
364
|
-
) : null}
|
|
365
|
-
</div>
|
|
366
|
-
<Input
|
|
367
|
-
id={field.key}
|
|
368
|
-
type={
|
|
369
|
-
"secret" in field && field.secret
|
|
370
|
-
? "password"
|
|
371
|
-
: "text"
|
|
372
|
-
}
|
|
373
|
-
value={values[field.key] ?? ""}
|
|
374
|
-
onChange={(event) => {
|
|
375
|
-
setValues((current) => ({
|
|
376
|
-
...current,
|
|
377
|
-
[field.key]: event.target.value,
|
|
378
|
-
}));
|
|
379
|
-
if (errors[field.key]) {
|
|
380
|
-
setErrors((current) => {
|
|
381
|
-
const next = { ...current };
|
|
382
|
-
delete next[field.key];
|
|
383
|
-
return next;
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
}}
|
|
387
|
-
placeholder={
|
|
388
|
-
configured
|
|
389
|
-
? t("settings.replaceKey")
|
|
390
|
-
: field.placeholder
|
|
391
|
-
}
|
|
392
|
-
autoComplete="off"
|
|
393
|
-
disabled={saving}
|
|
394
|
-
className={
|
|
395
|
-
errors[field.key] ? "border-destructive" : undefined
|
|
396
|
-
}
|
|
397
|
-
/>
|
|
398
|
-
{errors[field.key] ? (
|
|
399
|
-
<p className="text-[11px] text-destructive">
|
|
400
|
-
{errors[field.key]}
|
|
401
|
-
</p>
|
|
402
|
-
) : null}
|
|
403
|
-
</div>
|
|
404
|
-
);
|
|
405
|
-
})}
|
|
406
|
-
</div>
|
|
407
|
-
|
|
408
|
-
<div className="flex items-center justify-end gap-2">
|
|
409
|
-
{S3_STORAGE_FIELDS.some(
|
|
410
|
-
(field) => secrets.configured[field.key],
|
|
411
|
-
) ? (
|
|
412
|
-
<Button
|
|
413
|
-
type="button"
|
|
414
|
-
variant="ghost"
|
|
415
|
-
size="sm"
|
|
416
|
-
onClick={handleClearAll}
|
|
417
|
-
disabled={clearing || saving}
|
|
418
|
-
className="text-muted-foreground hover:text-destructive"
|
|
419
|
-
>
|
|
420
|
-
{clearing ? (
|
|
421
|
-
<IconLoader2 className="h-4 w-4 animate-spin" />
|
|
422
|
-
) : (
|
|
423
|
-
<IconTrash className="h-4 w-4" />
|
|
424
|
-
)}
|
|
425
|
-
{t("settings.clearAllS3")}
|
|
426
|
-
</Button>
|
|
427
|
-
) : null}
|
|
428
|
-
<Button
|
|
429
|
-
onClick={handleSave}
|
|
430
|
-
disabled={saving || storageStatus.isLoading}
|
|
431
|
-
>
|
|
432
|
-
{saving && <IconLoader2 className="h-4 w-4 animate-spin" />}
|
|
433
|
-
{t("settings.saveStorage")}
|
|
434
|
-
</Button>
|
|
435
|
-
</div>
|
|
436
|
-
</div>
|
|
437
|
-
</CollapsibleContent>
|
|
438
361
|
</div>
|
|
439
|
-
</
|
|
440
|
-
</
|
|
441
|
-
</
|
|
362
|
+
</CollapsibleContent>
|
|
363
|
+
</Collapsible>
|
|
364
|
+
</SettingsGroup>
|
|
442
365
|
);
|
|
443
366
|
}
|
|
@@ -675,11 +675,11 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
675
675
|
"Builder.io is the primary storage path for Clips uploads. S3 is available when you need to bring your own bucket.",
|
|
676
676
|
checkingBuilder: "Checking Builder.io",
|
|
677
677
|
builderConnected: "Builder.io connected",
|
|
678
|
-
connectBuilder: "Use Builder.io
|
|
678
|
+
connectBuilder: "Use Builder.io",
|
|
679
679
|
builderConnectedFor: "Using Builder.io for {{orgName}}.",
|
|
680
680
|
builderConnectedGeneric: "New clips use the connected Builder.io provider.",
|
|
681
681
|
builderIncludes:
|
|
682
|
-
"
|
|
682
|
+
"Builder.io's free tier includes object storage, uploads, and managed transcription for new clips.",
|
|
683
683
|
s3Title: "S3-compatible storage",
|
|
684
684
|
secondary: "Secondary",
|
|
685
685
|
active: "Active",
|
|
@@ -705,8 +705,7 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
705
705
|
"Bucket name must be 3–63 lowercase letters, numbers, or hyphens",
|
|
706
706
|
s3RegionInvalid: 'Must be a valid region (e.g. us-east-1) or "auto"',
|
|
707
707
|
apiSetup: "AI setup",
|
|
708
|
-
apiSetupDescription:
|
|
709
|
-
"Connect AI with Builder.io free credits or your own LLM keys.",
|
|
708
|
+
apiSetupDescription: "Choose how Clips connects to AI.",
|
|
710
709
|
builderEasySetup: "Builder.io free credits",
|
|
711
710
|
builderAiAvailable:
|
|
712
711
|
"Included AI credits and managed transcription are available for Clips.",
|
|
@@ -714,8 +713,13 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
714
713
|
"Use Builder.io first for included AI credits, object storage, uploads, and managed transcription.",
|
|
715
714
|
providerKeyTitle: "Bring your own provider key",
|
|
716
715
|
providerKeyDescription:
|
|
717
|
-
"
|
|
716
|
+
"Choose Anthropic, OpenAI, OpenRouter, Gemini, Groq, Mistral, Cohere, or Ollama for provider-billed usage.",
|
|
718
717
|
providerKeysSet: "{{count}} set",
|
|
718
|
+
providerActionTitle: "AI provider",
|
|
719
|
+
providerActionDescription:
|
|
720
|
+
"Builder.io includes a free tier, or use custom keys.",
|
|
721
|
+
providerManage: "Manage",
|
|
722
|
+
providerCustomKeys: "Custom keys",
|
|
719
723
|
checkingProviderKeys: "Checking provider keys…",
|
|
720
724
|
keySet: "Set",
|
|
721
725
|
keyCleared: "Storage credentials cleared",
|
|
@@ -725,8 +729,7 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
725
729
|
apiKeySaved: "API key saved",
|
|
726
730
|
apiKeyFailed: "Failed to save key",
|
|
727
731
|
slackTitle: "Agent-Native Clips for Slack",
|
|
728
|
-
slackDescription:
|
|
729
|
-
"Share a public clip, paste the link in Slack, and it plays inline — no extra steps for viewers. Connect each workspace once.",
|
|
732
|
+
slackDescription: "Preview public Clips links inline in Slack.",
|
|
730
733
|
checkingSlack: "Checking Slack",
|
|
731
734
|
slackConnected_one: "{{count}} workspace connected",
|
|
732
735
|
slackConnected_other: "{{count}} workspaces connected",
|
|
@@ -1145,7 +1148,7 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
1145
1148
|
"Didn't hear back from Builder in 5 minutes. Check the popup and try again.",
|
|
1146
1149
|
builderConnected: "Builder.io connected",
|
|
1147
1150
|
waitingForBuilder: "Waiting for Builder...",
|
|
1148
|
-
connectBuilder: "Use Builder.io
|
|
1151
|
+
connectBuilder: "Use Builder.io",
|
|
1149
1152
|
free: "Free",
|
|
1150
1153
|
configureS3: "configure S3-compatible storage",
|
|
1151
1154
|
whyPrompt: "Why am I seeing this?",
|