@kortix/ui 0.14.7 → 0.14.8
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/_vendor/kortix-shared.js +1 -1
- package/dist/_vendor/shared/runtime-versions.d.ts +4 -0
- package/dist/access/access/access-dialog-share.js +4 -7
- package/dist/access/access/access-dialog.js +2 -1
- package/dist/access/access/principal-picker.js +6 -5
- package/dist/customize/agents/agent-cover-card.d.ts +17 -0
- package/dist/customize/agents/agent-cover-card.js +13 -0
- package/dist/customize/agents/agent-page.js +6 -33
- package/dist/customize/agents/agents-page.js +43 -49
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +1 -0
- package/dist/customize/migrate-to-v2/migration-prompt.js +1 -0
- package/dist/customize/sections/view/channels-view.js +2 -6
- package/dist/customize/shared/new-entity-menu.js +4 -1
- package/dist/customize/skills/skills-page.js +4 -5
- package/dist/customize/triggers/schedule/then-fields.js +1 -5
- package/dist/customize/triggers/schedule-view.js +4 -2
- package/dist/i18n/en.d.ts +60 -12
- package/dist/i18n/en.js +62 -14
- package/dist/internal/components/agent-mark.d.ts +38 -0
- package/dist/internal/components/agent-mark.js +38 -0
- package/dist/internal/lib/pixel-mark.d.ts +33 -0
- package/dist/internal/lib/pixel-mark.js +152 -0
- package/dist/internal/lib/use-project-feature-flags.js +3 -3
- package/dist/markdown/genui/components/inline.d.ts +1 -1
- package/dist/markdown/setup-links/app-credentials-form.d.ts +12 -0
- package/dist/markdown/setup-links/app-credentials-form.js +115 -0
- package/dist/markdown/setup-links/secret-intake-form.d.ts +10 -0
- package/dist/markdown/setup-links/secret-intake-form.js +1 -1
- package/dist/primitives/entity-avatar.d.ts +4 -1
- package/dist/primitives/entity-avatar.js +4 -2
- package/dist/primitives/user-avatar.d.ts +3 -1
- package/dist/primitives/user-avatar.js +4 -2
- package/dist/providers/ui-provider.d.ts +1 -1
- package/dist/session/composer/agent-selector.d.ts +7 -1
- package/dist/session/composer/agent-selector.js +20 -10
- package/dist/session/composer/context-usage.d.ts +5 -0
- package/dist/session/composer/context-usage.js +6 -1
- package/dist/session/composer/token-progress.js +4 -4
- package/dist/session/header/export-transcript-modal.d.ts +3 -2
- package/dist/session/header/export-transcript-modal.js +6 -3
- package/dist/session/models/model-selector.d.ts +3 -1
- package/dist/session/models/model-selector.js +3 -2
- package/dist/session/panel/easy/plan-card.d.ts +2 -0
- package/dist/session/panel/easy/plan-card.js +2 -0
- package/dist/session/thread/plan-surface.d.ts +1 -0
- package/dist/session/thread/plan-surface.js +1 -0
- package/dist/session/thread/session-chat.js +2 -2
- package/dist/session/thread/session-context-metrics.d.ts +15 -0
- package/dist/session/thread/session-context-metrics.js +10 -1
- package/dist/session/thread/session-context-modal.d.ts +4 -2
- package/dist/session/thread/session-context-modal.js +16 -9
- package/dist/session/thread/transcript.d.ts +4 -0
- package/dist/session/thread/transcript.js +18 -5
- package/dist/session/thread/turn-share.d.ts +16 -0
- package/dist/session/thread/turn-share.js +162 -0
- package/dist/session/tool/tools/apply-patch-tool.d.ts +1 -0
- package/dist/session/tool/tools/apply-patch-tool.js +1 -0
- package/dist/session/tool/tools/pty-kill-tool.d.ts +1 -0
- package/dist/session/tool/tools/pty-kill-tool.js +1 -0
- package/dist/session/tool/tools/pty-read-tool.d.ts +2 -0
- package/dist/session/tool/tools/pty-read-tool.js +2 -0
- package/dist/session/tool/tools/pty-spawn-tool.d.ts +1 -0
- package/dist/session/tool/tools/pty-spawn-tool.js +1 -0
- package/dist/session/tool/tools/pty-write-tool.d.ts +1 -0
- package/dist/session/tool/tools/pty-write-tool.js +1 -0
- package/dist/session/tool/tools/todo-write-tool.d.ts +1 -0
- package/dist/session/tool/tools/todo-write-tool.js +1 -0
- package/dist/session/turn/message-author-label.js +6 -2
- package/dist/session/turn/plan-anchor.d.ts +3 -0
- package/dist/session/turn/plan-anchor.js +3 -0
- package/dist/session/turn/plan-card.d.ts +7 -0
- package/dist/session/turn/plan-card.js +7 -0
- package/dist/styles.css +1 -1
- package/dist/terminal/session-terminal-connect-bar.js +2 -1
- package/dist/workspace/sidebar/session-brief-hover-card.js +28 -1
- package/package.json +11 -3
- package/dist/customize/agents/agent-nav.prototype.d.ts +0 -35
- package/dist/customize/agents/agent-nav.prototype.js +0 -95
|
@@ -30,7 +30,10 @@ export function RichRowBody({ icon: Glyph, title, description, }) {
|
|
|
30
30
|
* A tab with one common case that needs no form leads with it (`quick`):
|
|
31
31
|
* Connectors → "MCP server" (KRTX-2185).
|
|
32
32
|
*/
|
|
33
|
-
export function NewEntityMenu({ label = 'New',
|
|
33
|
+
export function NewEntityMenu({ label = 'New',
|
|
34
|
+
// `default` is `h-9`, the height of the `size="sm"` search input every
|
|
35
|
+
// Customize header puts beside it. `sm` (`h-8`) left the pair 4px apart.
|
|
36
|
+
size = 'default', variant = 'secondary', caret = true, pending = false, onChat, manual, quick, }) {
|
|
34
37
|
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
35
38
|
if (!manual) {
|
|
36
39
|
return (_jsxs(Button, { variant: variant, size: size, className: "gap-1.5", disabled: pending, onClick: onChat, children: [pending ? _jsx(Loading, { className: "size-4 shrink-0" }) : _jsx(PlusIcon, { className: "size-4" }), label] }));
|
|
@@ -96,10 +96,9 @@ export function SkillsPage({ projectId }) {
|
|
|
96
96
|
// One control, two labels. The header has a title beside it and can be terse;
|
|
97
97
|
// the empty state is the whole screen and has to name what it creates. Both
|
|
98
98
|
// offer the same two ways in, so they cannot drift apart.
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
const createButton = (label) => canWrite ? (_jsx(NewEntityMenu, { label: label, pending: configure.pending, onChat: () => configure.start(newConfigPrompt('skill')), manual: {
|
|
99
|
+
// The header button is `h-9`, the height of the `size="sm"` search input
|
|
100
|
+
// beside it. The empty state keeps `sm` to match its `sm` docs link.
|
|
101
|
+
const createButton = (label, size) => canWrite ? (_jsx(NewEntityMenu, { label: label, size: size, pending: configure.pending, onChat: () => configure.start(newConfigPrompt('skill')), manual: {
|
|
103
102
|
label: tI18nComplete.raw('texta38668224f1a'),
|
|
104
103
|
description: tI18nComplete.raw('textedac6130dac7'),
|
|
105
104
|
onSelect: () => setFormOpen(true),
|
|
@@ -108,7 +107,7 @@ export function SkillsPage({ projectId }) {
|
|
|
108
107
|
// The copy invites an action, so the action is here — not only in
|
|
109
108
|
// the header. Docs stays as the secondary, for the reader who has
|
|
110
109
|
// no write permission and gets no primary at all.
|
|
111
|
-
action: createButton('Create a skill'), secondaryAction: _jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "gap-1.5", children: _jsx("a", { href: "
|
|
110
|
+
action: createButton('Create a skill', 'sm'), secondaryAction: _jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "gap-1.5", children: _jsx("a", { href: "/docs/project/agents#skills", target: "_blank", rel: "noopener noreferrer", children: tI18nComplete.raw('text7af023c43013') }) }) })), children: filtered.map((skill) => (_jsx(CatalogCard, { title: skill.name, description: skill.description, onClick: () => setSelectedPath(skill.path) }, skill.path))) }), _jsx(EntityDetailModal, { projectId: projectId, entity: detail.record, kind: "skill", removable: true, open: detail.open, isResolving: detail.isResolving, onOpenChange: (next) => {
|
|
112
111
|
if (!next)
|
|
113
112
|
setSelectedPath(null);
|
|
114
113
|
} }), _jsx(NewSkillModal, { projectId: projectId, open: formOpen, onOpenChange: setFormOpen })] }));
|
|
@@ -28,9 +28,5 @@ export function ThenFields({ agents, draft, patch, payloadSchema, error, }) {
|
|
|
28
28
|
el?.setSelectionRange(at + insert.length, at + insert.length);
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
// up with every other field. The selector's own button fills it, label left,
|
|
33
|
-
// caret right, like a Select trigger.
|
|
34
|
-
const panel = 'bg-popover border-border flex h-9 w-full items-center rounded-md border px-0.5 [&_button]:h-8 [&_button]:w-full [&_button]:justify-between';
|
|
35
|
-
return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Textarea, { value: draft.instruction, ref: promptRef, onChange: (e) => patch({ instruction: e.target.value }), "aria-label": tI18nComplete.raw('text112f3ccb1b36'), "aria-invalid": error ? true : undefined, placeholder: tI18nComplete.raw('text2438ee64fbf9'), rows: 3, className: "leading-relaxed" }), _jsx(InlineError, { message: error }), draft.kind === 'event' && draft.eventType ? (_jsx(PromptVariableHints, { payloadSchema: payloadSchema, onInsert: insertVariable })) : (_jsx("p", { className: "text-muted-foreground text-xs leading-relaxed text-pretty", children: tI18nComplete.raw('text03956d4b33dc') }))] }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs", children: tI18nComplete.raw('text11b39c93777e') }), _jsx("div", { className: panel, children: _jsx(AgentSelector, { agents: agents, selectedAgent: draft.agent, triggerLabelClassName: "max-w-none", onSelect: (agent) => patch({ agent }) }) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs", children: tI18nComplete.raw('text5e2c614c23f0') }), _jsx("div", { className: panel, children: _jsx(ModelSelector, { models: models, providers: providers, selectedModel: draft.model, unsetLabel: tI18nComplete.raw('text57069bbd0d2e'), triggerLabelClassName: "max-w-none", onSelect: (model) => patch({ model }) }) })] })] })] }));
|
|
31
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Textarea, { value: draft.instruction, ref: promptRef, onChange: (e) => patch({ instruction: e.target.value }), "aria-label": tI18nComplete.raw('text112f3ccb1b36'), "aria-invalid": error ? true : undefined, placeholder: tI18nComplete.raw('text2438ee64fbf9'), rows: 3, className: "leading-relaxed" }), _jsx(InlineError, { message: error }), draft.kind === 'event' && draft.eventType ? (_jsx(PromptVariableHints, { payloadSchema: payloadSchema, onInsert: insertVariable })) : (_jsx("p", { className: "text-muted-foreground text-xs leading-relaxed text-pretty", children: tI18nComplete.raw('text03956d4b33dc') }))] }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs", children: tI18nComplete.raw('text11b39c93777e') }), _jsx(AgentSelector, { agents: agents, selectedAgent: draft.agent, appearance: "field", onSelect: (agent) => patch({ agent }) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs", children: tI18nComplete.raw('text5e2c614c23f0') }), _jsx(ModelSelector, { models: models, providers: providers, selectedModel: draft.model, unsetLabel: tI18nComplete.raw('text57069bbd0d2e'), appearance: "field", onSelect: (model) => patch({ model }) })] })] })] }));
|
|
36
32
|
}
|
|
@@ -84,7 +84,9 @@ export function TriggerToolbarMenu({ canManage, paused, isPending, onToggle, onS
|
|
|
84
84
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
85
85
|
if (!canManage)
|
|
86
86
|
return null;
|
|
87
|
-
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", size: "icon-base",
|
|
87
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", size: "icon-base",
|
|
88
|
+
// `size-9`: the New trigger button and the search input beside it are `h-9`.
|
|
89
|
+
className: "size-9", disabled: isPending, "aria-label": tI18nComplete.raw('textd47d7cb0e4f8'), children: _jsx(DotsThreeIcon, { className: "text-muted-foreground size-4 shrink-0" }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-76", children: [_jsx(DropdownMenuItem, { className: RICH_ROW_CLASS, disabled: paused, onSelect: () => onToggle(true), children: _jsx(RichRowBody, { icon: PauseIcon, title: tI18nComplete.raw('text0b6258b50010'), description: tI18nComplete.raw('textdae75dce541f') }) }), _jsx(DropdownMenuItem, { className: RICH_ROW_CLASS, disabled: !paused, onSelect: () => onToggle(false), children: _jsx(RichRowBody, { icon: PlayIcon, title: tI18nComplete.raw('text43e673c5503d'), description: tI18nComplete.raw('textced57bebd466') }) }), onSelectMode ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onSelect: onSelectMode, children: [_jsx(CheckSquareIcon, {}), tI18nComplete.raw('text2a78025de6aa')] })] })) : null] })] }));
|
|
88
90
|
}
|
|
89
91
|
/**
|
|
90
92
|
* The project-wide pause switch (`PATCH /projects/:id/triggers/activation`):
|
|
@@ -387,7 +389,7 @@ export function ScheduleView({ projectId }) {
|
|
|
387
389
|
Both are hidden until the list has loaded — neither means anything
|
|
388
390
|
on an error or a 403. */
|
|
389
391
|
showContent ? (
|
|
390
|
-
// Search, then one group: ⋯ and New trigger, both `secondary` at `h-
|
|
392
|
+
// Search, then one group: ⋯ and New trigger, both `secondary` at `h-9`, the search input's height.
|
|
391
393
|
_jsxs(ButtonGroup, { children: [triggers.length > 0 || paused ? (_jsx(TriggerActivationMenu, { projectId: projectId, onSelectMode: triggers.length > 0 ? enterSelectMode : undefined })) : null, canWrite ? (_jsx(NewEntityMenu, { label: copy.createLabel, pending: configure.pending, onChat: () => configure.start(newConfigPrompt('trigger')), manual: { onSelect: () => openCreate() }, caret: false })) : null] })) : undefined, children: [_jsxs("div", { className: "space-y-4", children: [accountPaused && showContent && (_jsxs(Alert, { variant: "warning", children: [_jsx(AlertTitle, { children: tAutomations('bannerTitle') }), _jsx(AlertDescription, { children: tAutomations('bannerDescription') })] })), paused && showContent && (_jsxs(Alert, { variant: "warning", children: [_jsx(AlertTitle, { children: tI18nComplete.raw('textb18b93a52cd2') }), _jsx(AlertDescription, { children: tI18nComplete.raw('textc9e9d972eda2') }), controls.canUpdate ? (_jsx(AlertActions, { children: _jsxs(Button, { variant: "outline", size: "sm", disabled: resumeAll.isPending, onClick: () => resumeAll.mutate(false), children: [resumeAll.isPending ? _jsx(Loading, { className: "size-3.5 shrink-0" }) : null, tI18nComplete.raw('text43e673c5503d')] }) })) : null] })), triggersQuery.isLoading ? (_jsx("div", { className: "space-y-1", children: Array.from({ length: 5 }).map((_, i) => (
|
|
392
394
|
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-length placeholder
|
|
393
395
|
_jsx(Skeleton, { className: "h-10 rounded-md" }, i))) })) : isForbidden ? (_jsxs(Alert, { variant: "warning", children: [_jsx(AlertTitle, { children: tI18nComplete.raw('textabb84be05cfa') }), _jsxs(AlertDescription, { children: [tI18nComplete.raw('text22cd1f210415'), " ", copy.noun, tI18nComplete.raw('text382584f2456e')] })] })) : triggersQuery.isError ? (_jsx(ErrorState, { size: "sm", title: tI18nComplete('text7ce02a51e3dd', { value0: copy.noun }), description: triggersQuery.error?.message ?? tI18nComplete.raw('text0c953ab32c60'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => triggersQuery.refetch(), children: tI18nComplete.raw('textd8b8392e2c54') }) })) : filter !== 'all' && ofKind.length === 0 ? (_jsx(EmptyState, { size: "sm", title: kindCopy[filter].emptyTitle })) : triggers.length === 0 ? (_jsx(EmptyState, { icon: LightningIcon, title: copy.emptyTitle, description: copy.emptyBody, className: "py-12", action: canWrite ? (_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: () => openCreate(), children: [_jsx(PlusIcon, { className: "size-4 shrink-0" }), copy.createLabel] })) : undefined })) : filtered.length === 0 ? (_jsxs("p", { className: "text-muted-foreground px-3 py-6 text-center text-xs", children: [tI18nComplete.raw('text965b516df3ba'), ' ', _jsx("span", { className: "text-foreground font-medium", children: debouncedQuery }), "."] })) : (_jsx(TriggerList, { triggers: filtered, groups: appGroups, eventNames: eventNames, projectPaused: paused, selectedSlug: selected?.slug ?? null, runningSlug: run.isPending ? (run.variables?.slug ?? null) : liveSlug, onOpen: (t) => openTrigger(t.slug), selection: selectMode
|
package/dist/i18n/en.d.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
declare const catalog: {
|
|
2
|
-
agentNavPrototype: {
|
|
3
|
-
variantRail: string;
|
|
4
|
-
variantTabs: string;
|
|
5
|
-
variantGroups: string;
|
|
6
|
-
variantInline: string;
|
|
7
|
-
previousVariant: string;
|
|
8
|
-
nextVariant: string;
|
|
9
|
-
};
|
|
10
2
|
repositoryDisconnected: {
|
|
11
3
|
title: string;
|
|
12
4
|
reconnect: string;
|
|
@@ -795,10 +787,6 @@ declare const catalog: {
|
|
|
795
787
|
name: string;
|
|
796
788
|
description: string;
|
|
797
789
|
};
|
|
798
|
-
pi_harness: {
|
|
799
|
-
name: string;
|
|
800
|
-
description: string;
|
|
801
|
-
};
|
|
802
790
|
genui: {
|
|
803
791
|
name: string;
|
|
804
792
|
description: string;
|
|
@@ -843,6 +831,10 @@ declare const catalog: {
|
|
|
843
831
|
name: string;
|
|
844
832
|
description: string;
|
|
845
833
|
};
|
|
834
|
+
workspace_volume: {
|
|
835
|
+
name: string;
|
|
836
|
+
description: string;
|
|
837
|
+
};
|
|
846
838
|
};
|
|
847
839
|
};
|
|
848
840
|
upgrades: {
|
|
@@ -7251,5 +7243,61 @@ declare const catalog: {
|
|
|
7251
7243
|
manage: string;
|
|
7252
7244
|
overviewTitle: string;
|
|
7253
7245
|
};
|
|
7246
|
+
connectAppForm: {
|
|
7247
|
+
title: string;
|
|
7248
|
+
description: string;
|
|
7249
|
+
loading: string;
|
|
7250
|
+
stepsTitle: string;
|
|
7251
|
+
step1: string;
|
|
7252
|
+
step2: string;
|
|
7253
|
+
step3: string;
|
|
7254
|
+
step4: string;
|
|
7255
|
+
sameOrganization: string;
|
|
7256
|
+
storeLabel: string;
|
|
7257
|
+
clientIdLabel: string;
|
|
7258
|
+
clientSecretLabel: string;
|
|
7259
|
+
submit: string;
|
|
7260
|
+
connecting: string;
|
|
7261
|
+
missingFields: string;
|
|
7262
|
+
failed: string;
|
|
7263
|
+
secretNote: string;
|
|
7264
|
+
connectedTitle: string;
|
|
7265
|
+
connectedDescription: string;
|
|
7266
|
+
closeWindow: string;
|
|
7267
|
+
expiredTitle: string;
|
|
7268
|
+
invalidTitle: string;
|
|
7269
|
+
staleTitle: string;
|
|
7270
|
+
startAgain: string;
|
|
7271
|
+
};
|
|
7272
|
+
turnShare: {
|
|
7273
|
+
shareResponse: string;
|
|
7274
|
+
whatToInclude: string;
|
|
7275
|
+
responseOnly: string;
|
|
7276
|
+
responseOnlyHint: string;
|
|
7277
|
+
promptAndResponse: string;
|
|
7278
|
+
promptAndResponseHint: string;
|
|
7279
|
+
publicLink: string;
|
|
7280
|
+
publicLinkHint: string;
|
|
7281
|
+
turnOffLink: string;
|
|
7282
|
+
cancel: string;
|
|
7283
|
+
copyLink: string;
|
|
7284
|
+
copied: string;
|
|
7285
|
+
linkCopied: string;
|
|
7286
|
+
linkUpdated: string;
|
|
7287
|
+
responseShared: string;
|
|
7288
|
+
stale: string;
|
|
7289
|
+
updateLink: string;
|
|
7290
|
+
loadError: string;
|
|
7291
|
+
shareError: string;
|
|
7292
|
+
unshareError: string;
|
|
7293
|
+
copyError: string;
|
|
7294
|
+
tryKortix: string;
|
|
7295
|
+
goneTitle: string;
|
|
7296
|
+
goneHint: string;
|
|
7297
|
+
busyTitle: string;
|
|
7298
|
+
busyHint: string;
|
|
7299
|
+
fallbackTitle: string;
|
|
7300
|
+
stopNote: string;
|
|
7301
|
+
};
|
|
7254
7302
|
};
|
|
7255
7303
|
export default catalog;
|
package/dist/i18n/en.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
// Generated by scripts/gen-i18n-catalog.mjs from apps/web/translations/en.json. Do not edit.
|
|
2
2
|
const catalog = {
|
|
3
|
-
"agentNavPrototype": {
|
|
4
|
-
"variantRail": "Left rail (today)",
|
|
5
|
-
"variantTabs": "Grouped underline tabs",
|
|
6
|
-
"variantGroups": "Group switch + tabs",
|
|
7
|
-
"variantInline": "Vertical tabs with values",
|
|
8
|
-
"previousVariant": "Previous variant",
|
|
9
|
-
"nextVariant": "Next variant"
|
|
10
|
-
},
|
|
11
3
|
"repositoryDisconnected": {
|
|
12
4
|
"title": "GitHub disconnected",
|
|
13
5
|
"reconnect": "Reconnect GitHub",
|
|
@@ -796,10 +788,6 @@ const catalog = {
|
|
|
796
788
|
"name": "Pooled Provider Secrets",
|
|
797
789
|
"description": "Members connect their own ChatGPT subscriptions and provider keys, share them when needed, and choose which ones each session uses."
|
|
798
790
|
},
|
|
799
|
-
"pi_harness": {
|
|
800
|
-
"name": "Pi Harness (in-sandbox)",
|
|
801
|
-
"description": "Run sessions on the pi harness inside the session sandbox instead of OpenCode. Off, `runtime: pi` in the manifest still selects pi."
|
|
802
|
-
},
|
|
803
791
|
"genui": {
|
|
804
792
|
"name": "Generative UI",
|
|
805
793
|
"description": "The agent may answer with cards, comparisons, charts, maps, and tabs instead of long text."
|
|
@@ -843,6 +831,10 @@ const catalog = {
|
|
|
843
831
|
"goals": {
|
|
844
832
|
"name": "Goals",
|
|
845
833
|
"description": "Give an agent an objective it owns until an independent check confirms the outcome. It plans, works, waits, follows up with people, and keeps its state in a Goals folder in Files. Needs Volumes and Reminders on."
|
|
834
|
+
},
|
|
835
|
+
"workspace_volume": {
|
|
836
|
+
"name": "Workspace volume",
|
|
837
|
+
"description": "Keeps each new session's /workspace on its own volume, so a stopped sandbox can be deleted and the next open boots a new one on the same files and conversation. Kortix enables it per project."
|
|
846
838
|
}
|
|
847
839
|
}
|
|
848
840
|
},
|
|
@@ -1351,8 +1343,8 @@ const catalog = {
|
|
|
1351
1343
|
}
|
|
1352
1344
|
},
|
|
1353
1345
|
"sessionDelete": {
|
|
1354
|
-
"description": "Deletes <name>{label}</name> and removes its sandbox. You can restore it from Recently deleted for {days} days. After that, its messages and
|
|
1355
|
-
"bulkDescription": "Deletes each selected session and removes its sandbox. You can restore each one from Recently deleted for {days} days. After that, its messages and
|
|
1346
|
+
"description": "Deletes <name>{label}</name> and removes its sandbox. You can restore it from Recently deleted for {days} days. After that, its messages, files and branch are deleted.",
|
|
1347
|
+
"bulkDescription": "Deletes each selected session and removes its sandbox. You can restore each one from Recently deleted for {days} days. After that, its messages, files and branch are deleted.",
|
|
1356
1348
|
"restoring": "Restoring the session…",
|
|
1357
1349
|
"undo": "Undo",
|
|
1358
1350
|
"restored": "Session restored",
|
|
@@ -7251,6 +7243,62 @@ const catalog = {
|
|
|
7251
7243
|
"agentEditor": {
|
|
7252
7244
|
"manage": "Manage",
|
|
7253
7245
|
"overviewTitle": "Overview"
|
|
7246
|
+
},
|
|
7247
|
+
"connectAppForm": {
|
|
7248
|
+
"title": "Connect Shopify",
|
|
7249
|
+
"description": "Kortix reaches your store through a Shopify app in your organization. Enter its credentials once.",
|
|
7250
|
+
"loading": "Loading the form…",
|
|
7251
|
+
"stepsTitle": "Create the app in Shopify",
|
|
7252
|
+
"step1": "Open the <link>Shopify Dev Dashboard</link> and create an app in the organization that owns your store.",
|
|
7253
|
+
"step2": "On the app's version, select the Admin API scopes your agents need, then release the version.",
|
|
7254
|
+
"step3": "Install the app on your store.",
|
|
7255
|
+
"step4": "Copy the Client ID and Client secret from the app's Settings.",
|
|
7256
|
+
"sameOrganization": "The app and the store must be in the same Shopify organization.",
|
|
7257
|
+
"storeLabel": "Store",
|
|
7258
|
+
"clientIdLabel": "Client ID",
|
|
7259
|
+
"clientSecretLabel": "Client secret",
|
|
7260
|
+
"submit": "Connect {app}",
|
|
7261
|
+
"connecting": "Connecting…",
|
|
7262
|
+
"missingFields": "Enter the store, the Client ID and the Client secret.",
|
|
7263
|
+
"failed": "Could not connect. Check your connection and try again.",
|
|
7264
|
+
"secretNote": "Kortix sends the secret to Composio, which runs the connection. Kortix keeps no copy.",
|
|
7265
|
+
"connectedTitle": "{app} is connected",
|
|
7266
|
+
"connectedDescription": "Kortix reaches {store}. You can close this window.",
|
|
7267
|
+
"closeWindow": "You can close this window.",
|
|
7268
|
+
"expiredTitle": "This link expired",
|
|
7269
|
+
"invalidTitle": "This link does not work",
|
|
7270
|
+
"staleTitle": "This link was replaced",
|
|
7271
|
+
"startAgain": "Start Connect again in Kortix."
|
|
7272
|
+
},
|
|
7273
|
+
"turnShare": {
|
|
7274
|
+
"shareResponse": "Share response",
|
|
7275
|
+
"whatToInclude": "What to include",
|
|
7276
|
+
"responseOnly": "Response only",
|
|
7277
|
+
"responseOnlyHint": "Your prompt stays private",
|
|
7278
|
+
"promptAndResponse": "Prompt and response",
|
|
7279
|
+
"promptAndResponseHint": "Includes the prompt",
|
|
7280
|
+
"publicLink": "Public link",
|
|
7281
|
+
"publicLinkHint": "Anyone with the link can read it",
|
|
7282
|
+
"turnOffLink": "Turn off link",
|
|
7283
|
+
"cancel": "Cancel",
|
|
7284
|
+
"copyLink": "Copy link",
|
|
7285
|
+
"copied": "Copied",
|
|
7286
|
+
"linkCopied": "Link copied",
|
|
7287
|
+
"linkUpdated": "Link updated",
|
|
7288
|
+
"responseShared": "Response shared",
|
|
7289
|
+
"stale": "Response changed since you shared it",
|
|
7290
|
+
"updateLink": "Update link",
|
|
7291
|
+
"loadError": "Could not load the share settings. Try again.",
|
|
7292
|
+
"shareError": "Could not share the response. Try again.",
|
|
7293
|
+
"unshareError": "Could not stop sharing. Try again.",
|
|
7294
|
+
"copyError": "Could not copy the link. Copy it from the field.",
|
|
7295
|
+
"tryKortix": "Try Kortix",
|
|
7296
|
+
"goneTitle": "This link is no longer active",
|
|
7297
|
+
"goneHint": "The response it pointed to is no longer public.",
|
|
7298
|
+
"busyTitle": "This page is busy",
|
|
7299
|
+
"busyHint": "Refresh in a moment.",
|
|
7300
|
+
"fallbackTitle": "Shared response",
|
|
7301
|
+
"stopNote": "The link will stop working."
|
|
7254
7302
|
}
|
|
7255
7303
|
};
|
|
7256
7304
|
export default catalog;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @internal Kortix apps only. No semver: it may change in any release. */
|
|
2
|
+
import type { CSSProperties } from 'react';
|
|
3
|
+
/** Mark size → tile size. The mark is a multiple of 7, so each pixel lands on
|
|
4
|
+
* whole device pixels; any other size blurs the edges. Literal px because
|
|
5
|
+
* this repo's spacing scale is 0.23rem (`size-14` is 51.5px, not 56px). */
|
|
6
|
+
declare const TILE: {
|
|
7
|
+
readonly 14: 20;
|
|
8
|
+
readonly 21: 28;
|
|
9
|
+
readonly 28: 40;
|
|
10
|
+
readonly 42: 56;
|
|
11
|
+
readonly 56: 80;
|
|
12
|
+
};
|
|
13
|
+
export type AgentMarkSize = keyof typeof TILE;
|
|
14
|
+
/**
|
|
15
|
+
* The tile colours as CSS variables. `light-dark()` follows the
|
|
16
|
+
* `color-scheme` each theme sets in tokens.css, so one pair covers both themes.
|
|
17
|
+
* Set on the element that paints the tile; `AgentMarkGlyph` reads `--mark-ink`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function agentMarkVars(slug: string): CSSProperties;
|
|
20
|
+
/** The bare pixel figure, painted with `--mark-ink` from an ancestor. */
|
|
21
|
+
export declare function AgentMarkGlyph({ slug, size }: {
|
|
22
|
+
slug: string;
|
|
23
|
+
size: AgentMarkSize;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* An agent's pixel mark on its tile — the agent's face wherever it appears:
|
|
27
|
+
* pickers, rows, chips. Same slug, same mark (see `pixel-mark.ts`).
|
|
28
|
+
*/
|
|
29
|
+
export declare function AgentMark({ slug, size, tile, label, className, }: {
|
|
30
|
+
slug: string;
|
|
31
|
+
size?: AgentMarkSize;
|
|
32
|
+
/** Tile edge in px, when the tile must match a neighbour's height. */
|
|
33
|
+
tile?: number;
|
|
34
|
+
/** The hover hint. Defaults to the agent's display name. */
|
|
35
|
+
label?: string;
|
|
36
|
+
className?: string;
|
|
37
|
+
}): import("react").JSX.Element;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../lib/utils.js';
|
|
4
|
+
import { Hint } from '../../primitives/hint.js';
|
|
5
|
+
import { capitalizeWords, isMetaAgentName, META_AGENT_DISPLAY_NAME } from '../../_vendor/kortix-shared.js';
|
|
6
|
+
import { PIXEL_MARK_SIZE, pixelMark } from '../lib/pixel-mark.js';
|
|
7
|
+
/** Mark size → tile size. The mark is a multiple of 7, so each pixel lands on
|
|
8
|
+
* whole device pixels; any other size blurs the edges. Literal px because
|
|
9
|
+
* this repo's spacing scale is 0.23rem (`size-14` is 51.5px, not 56px). */
|
|
10
|
+
const TILE = { 14: 20, 21: 28, 28: 40, 42: 56, 56: 80 };
|
|
11
|
+
/**
|
|
12
|
+
* The tile colours as CSS variables. `light-dark()` follows the
|
|
13
|
+
* `color-scheme` each theme sets in tokens.css, so one pair covers both themes.
|
|
14
|
+
* Set on the element that paints the tile; `AgentMarkGlyph` reads `--mark-ink`.
|
|
15
|
+
*/
|
|
16
|
+
export function agentMarkVars(slug) {
|
|
17
|
+
const { tone } = pixelMark(slug);
|
|
18
|
+
return {
|
|
19
|
+
'--mark-tile': `light-dark(${tone.tile}, ${tone.tileDark})`,
|
|
20
|
+
'--mark-ink': `light-dark(${tone.ink}, ${tone.inkDark})`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** The bare pixel figure, painted with `--mark-ink` from an ancestor. */
|
|
24
|
+
export function AgentMarkGlyph({ slug, size }) {
|
|
25
|
+
return (_jsx("svg", { "aria-hidden": true, width: size, height: size, viewBox: `0 0 ${PIXEL_MARK_SIZE} ${PIXEL_MARK_SIZE}`, shapeRendering: "crispEdges", className: "shrink-0", children: _jsx("path", { d: pixelMark(slug).path, className: "fill-(--mark-ink)" }) }));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* An agent's pixel mark on its tile — the agent's face wherever it appears:
|
|
29
|
+
* pickers, rows, chips. Same slug, same mark (see `pixel-mark.ts`).
|
|
30
|
+
*/
|
|
31
|
+
export function AgentMark({ slug, size = 14, tile = TILE[size], label, className, }) {
|
|
32
|
+
// A mark is a face, not a name: the hover hint says whose face it is.
|
|
33
|
+
const mark = (_jsx("span", { "aria-hidden": true, style: { ...agentMarkVars(slug), width: tile, height: tile }, className: cn('inline-flex shrink-0 items-center justify-center bg-(--mark-tile)', size >= 28 ? 'rounded-md' : 'rounded-sm', className), children: _jsx(AgentMarkGlyph, { slug: slug, size: size }) }));
|
|
34
|
+
return (_jsx(Hint, { side: "top", sideOffset: 6, alignOffset: 0, label: label ?? agentLabel(slug), children: mark }));
|
|
35
|
+
}
|
|
36
|
+
function agentLabel(slug) {
|
|
37
|
+
return isMetaAgentName(slug) ? META_AGENT_DISPLAY_NAME : capitalizeWords(slug);
|
|
38
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** @internal Kortix apps only. No semver: it may change in any release. */
|
|
2
|
+
/**
|
|
3
|
+
* An agent's pixel mark: a 7×7 mirrored pixel figure derived from its slug.
|
|
4
|
+
*
|
|
5
|
+
* Same slug, same mark, on every surface and every device. Nothing is stored:
|
|
6
|
+
* the slug is hashed (FNV-1a), the hash seeds a PRNG (mulberry32), the PRNG
|
|
7
|
+
* fills the left half of the grid against a density mask, and the half is
|
|
8
|
+
* mirrored. A draw that fails the quality gate is redrawn from a salted seed,
|
|
9
|
+
* so retries stay deterministic. The tone comes from a second hash.
|
|
10
|
+
*
|
|
11
|
+
* Changing SIZE, MASK, the gate or PALETTES changes every agent's mark — the
|
|
12
|
+
* golden test in `pixel-mark.test.ts` exists to make that a deliberate act.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PIXEL_MARK_SIZE = 7;
|
|
15
|
+
export interface PixelMarkTone {
|
|
16
|
+
name: string;
|
|
17
|
+
tile: string;
|
|
18
|
+
ink: string;
|
|
19
|
+
/** Dark theme: the pair inverts, so the tile stays visible on a dark page. */
|
|
20
|
+
tileDark: string;
|
|
21
|
+
inkDark: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const PIXEL_MARK_TONES: readonly PixelMarkTone[];
|
|
24
|
+
type Grid = boolean[][];
|
|
25
|
+
export declare function fnv1a(input: string): number;
|
|
26
|
+
/** Readable at 14px, fills the frame, one connected body. */
|
|
27
|
+
export declare function passesPixelMarkGate(grid: Grid): boolean;
|
|
28
|
+
export declare function pixelMark(slug: string): {
|
|
29
|
+
grid: Grid;
|
|
30
|
+
path: string;
|
|
31
|
+
tone: PixelMarkTone;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An agent's pixel mark: a 7×7 mirrored pixel figure derived from its slug.
|
|
3
|
+
*
|
|
4
|
+
* Same slug, same mark, on every surface and every device. Nothing is stored:
|
|
5
|
+
* the slug is hashed (FNV-1a), the hash seeds a PRNG (mulberry32), the PRNG
|
|
6
|
+
* fills the left half of the grid against a density mask, and the half is
|
|
7
|
+
* mirrored. A draw that fails the quality gate is redrawn from a salted seed,
|
|
8
|
+
* so retries stay deterministic. The tone comes from a second hash.
|
|
9
|
+
*
|
|
10
|
+
* Changing SIZE, MASK, the gate or PALETTES changes every agent's mark — the
|
|
11
|
+
* golden test in `pixel-mark.test.ts` exists to make that a deliberate act.
|
|
12
|
+
*/
|
|
13
|
+
export const PIXEL_MARK_SIZE = 7;
|
|
14
|
+
const HALF = 4;
|
|
15
|
+
const MAX_ATTEMPTS = 256;
|
|
16
|
+
// Fill chance per cell, outer edge → spine. Dense centre, sparse edges, so the
|
|
17
|
+
// mirrored result reads as one body.
|
|
18
|
+
const MASK = [
|
|
19
|
+
[0.15, 0.3, 0.45, 0.55],
|
|
20
|
+
[0.3, 0.5, 0.6, 0.7],
|
|
21
|
+
[0.4, 0.6, 0.65, 0.7],
|
|
22
|
+
[0.5, 0.65, 0.7, 0.75],
|
|
23
|
+
[0.4, 0.55, 0.6, 0.65],
|
|
24
|
+
[0.3, 0.45, 0.5, 0.5],
|
|
25
|
+
[0.2, 0.35, 0.4, 0.35],
|
|
26
|
+
];
|
|
27
|
+
const tone = (name, tile, ink) => ({
|
|
28
|
+
name,
|
|
29
|
+
tile,
|
|
30
|
+
ink,
|
|
31
|
+
tileDark: ink,
|
|
32
|
+
inkDark: tile,
|
|
33
|
+
});
|
|
34
|
+
export const PIXEL_MARK_TONES = [
|
|
35
|
+
tone('graphite', '#EDEDED', '#191919'),
|
|
36
|
+
tone('sand', '#F1EBDD', '#6B5A3A'),
|
|
37
|
+
tone('moss', '#E6EDE0', '#3F5A33'),
|
|
38
|
+
tone('sea', '#E2ECF0', '#2E5566'),
|
|
39
|
+
tone('blue', '#E6EEFF', '#2457C5'),
|
|
40
|
+
tone('plum', '#EEE6F0', '#5E3A68'),
|
|
41
|
+
tone('clay', '#F3E6E0', '#7A4532'),
|
|
42
|
+
tone('slate', '#E4E7EC', '#3B4656'),
|
|
43
|
+
];
|
|
44
|
+
/** The built-in agent and the platform's Meta agent keep the brand tile. */
|
|
45
|
+
const BRAND = {
|
|
46
|
+
name: 'brand',
|
|
47
|
+
tile: '#1F1F1F',
|
|
48
|
+
ink: '#FFFFFF',
|
|
49
|
+
tileDark: '#2C2C2C',
|
|
50
|
+
inkDark: '#FFFFFF',
|
|
51
|
+
};
|
|
52
|
+
const RESERVED = { kortix: BRAND, meta: BRAND };
|
|
53
|
+
export function fnv1a(input) {
|
|
54
|
+
let h = 0x811c9dc5;
|
|
55
|
+
for (let i = 0; i < input.length; i++) {
|
|
56
|
+
h ^= input.charCodeAt(i);
|
|
57
|
+
h = Math.imul(h, 0x01000193);
|
|
58
|
+
}
|
|
59
|
+
return h >>> 0;
|
|
60
|
+
}
|
|
61
|
+
function mulberry32(seed) {
|
|
62
|
+
let a = seed;
|
|
63
|
+
return () => {
|
|
64
|
+
a = (a + 0x6d2b79f5) | 0;
|
|
65
|
+
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
66
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
67
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function draw(seed) {
|
|
71
|
+
const rand = mulberry32(seed);
|
|
72
|
+
return MASK.map((row) => {
|
|
73
|
+
const half = row.map((p) => rand() < p);
|
|
74
|
+
return [...half, half[2], half[1], half[0]];
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function largestComponent(grid) {
|
|
78
|
+
const seen = grid.map((row) => row.map(() => false));
|
|
79
|
+
let best = 0;
|
|
80
|
+
for (let r = 0; r < PIXEL_MARK_SIZE; r++)
|
|
81
|
+
for (let c = 0; c < PIXEL_MARK_SIZE; c++) {
|
|
82
|
+
if (!grid[r][c] || seen[r][c])
|
|
83
|
+
continue;
|
|
84
|
+
let size = 0;
|
|
85
|
+
const stack = [[r, c]];
|
|
86
|
+
seen[r][c] = true;
|
|
87
|
+
while (stack.length) {
|
|
88
|
+
const [y, x] = stack.pop();
|
|
89
|
+
size++;
|
|
90
|
+
for (const [ny, nx] of [[y + 1, x], [y - 1, x], [y, x + 1], [y, x - 1]]) {
|
|
91
|
+
if (grid[ny]?.[nx] && !seen[ny][nx]) {
|
|
92
|
+
seen[ny][nx] = true;
|
|
93
|
+
stack.push([ny, nx]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
best = Math.max(best, size);
|
|
98
|
+
}
|
|
99
|
+
return best;
|
|
100
|
+
}
|
|
101
|
+
function hasIsolatedPixel(grid) {
|
|
102
|
+
return grid.some((row, r) => row.some((on, c) => {
|
|
103
|
+
if (!on)
|
|
104
|
+
return false;
|
|
105
|
+
for (let dy = -1; dy <= 1; dy++)
|
|
106
|
+
for (let dx = -1; dx <= 1; dx++)
|
|
107
|
+
if ((dy || dx) && grid[r + dy]?.[c + dx])
|
|
108
|
+
return false;
|
|
109
|
+
return true;
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
/** Readable at 14px, fills the frame, one connected body. */
|
|
113
|
+
export function passesPixelMarkGate(grid) {
|
|
114
|
+
const filled = grid.flat().filter(Boolean).length;
|
|
115
|
+
if (filled < 18 || filled > 30)
|
|
116
|
+
return false;
|
|
117
|
+
const rows = grid.filter((row) => row.some(Boolean)).length;
|
|
118
|
+
const cols = grid[0].filter((_, c) => grid.some((row) => row[c])).length;
|
|
119
|
+
if (rows < 5 || cols < 5)
|
|
120
|
+
return false;
|
|
121
|
+
if (grid.filter((row) => row.every(Boolean)).length > 1)
|
|
122
|
+
return false;
|
|
123
|
+
if (grid.filter((row) => row[HALF - 1]).length < 3)
|
|
124
|
+
return false;
|
|
125
|
+
if (hasIsolatedPixel(grid))
|
|
126
|
+
return false;
|
|
127
|
+
return largestComponent(grid) >= Math.ceil(filled * 0.85);
|
|
128
|
+
}
|
|
129
|
+
/** One SVG path, horizontal runs merged. Render in `viewBox="0 0 7 7"`. */
|
|
130
|
+
function toPath(grid) {
|
|
131
|
+
let d = '';
|
|
132
|
+
grid.forEach((row, y) => {
|
|
133
|
+
for (let x = 0; x < PIXEL_MARK_SIZE;) {
|
|
134
|
+
if (!row[x]) {
|
|
135
|
+
x++;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const start = x;
|
|
139
|
+
while (x < PIXEL_MARK_SIZE && row[x])
|
|
140
|
+
x++;
|
|
141
|
+
d += `M${start} ${y}h${x - start}v1h-${x - start}z`;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return d;
|
|
145
|
+
}
|
|
146
|
+
export function pixelMark(slug) {
|
|
147
|
+
let grid = draw(fnv1a(slug));
|
|
148
|
+
for (let attempt = 1; !passesPixelMarkGate(grid) && attempt < MAX_ATTEMPTS; attempt++)
|
|
149
|
+
grid = draw(fnv1a(`${slug}:${attempt}`));
|
|
150
|
+
const tone = RESERVED[slug] ?? PIXEL_MARK_TONES[fnv1a(`${slug}#tone`) % PIXEL_MARK_TONES.length];
|
|
151
|
+
return { grid, path: toPath(grid), tone };
|
|
152
|
+
}
|
|
@@ -30,7 +30,6 @@ export function useProjectFeatureFlags(projectId) {
|
|
|
30
30
|
const warmSessions = useFeatureFlag(projectId, 'warm_sessions');
|
|
31
31
|
const secretsEgress = useFeatureFlag(projectId, 'secrets_egress');
|
|
32
32
|
const pooledProviderSecrets = useFeatureFlag(projectId, 'pooled_provider_secrets');
|
|
33
|
-
const piHarness = useFeatureFlag(projectId, 'pi_harness');
|
|
34
33
|
const genui = useFeatureFlag(projectId, 'genui');
|
|
35
34
|
const usRegion = useFeatureFlag(projectId, 'us_region');
|
|
36
35
|
const eventTriggers = useFeatureFlag(projectId, 'event_triggers');
|
|
@@ -42,6 +41,7 @@ export function useProjectFeatureFlags(projectId) {
|
|
|
42
41
|
const connectorsV2 = useFeatureFlag(projectId, 'connectors_v2');
|
|
43
42
|
const agentRooms = useFeatureFlag(projectId, 'agent_rooms');
|
|
44
43
|
const goals = useFeatureFlag(projectId, 'goals');
|
|
44
|
+
const workspaceVolume = useFeatureFlag(projectId, 'workspace_volume');
|
|
45
45
|
return {
|
|
46
46
|
flags: {
|
|
47
47
|
marketplace: marketplace.enabled,
|
|
@@ -53,7 +53,6 @@ export function useProjectFeatureFlags(projectId) {
|
|
|
53
53
|
warm_sessions: warmSessions.enabled,
|
|
54
54
|
secrets_egress: secretsEgress.enabled,
|
|
55
55
|
pooled_provider_secrets: pooledProviderSecrets.enabled,
|
|
56
|
-
pi_harness: piHarness.enabled,
|
|
57
56
|
genui: genui.enabled,
|
|
58
57
|
us_region: usRegion.enabled,
|
|
59
58
|
event_triggers: eventTriggers.enabled,
|
|
@@ -65,8 +64,9 @@ export function useProjectFeatureFlags(projectId) {
|
|
|
65
64
|
connectors_v2: connectorsV2.enabled,
|
|
66
65
|
agent_rooms: agentRooms.enabled,
|
|
67
66
|
goals: goals.enabled,
|
|
67
|
+
workspace_volume: workspaceVolume.enabled,
|
|
68
68
|
},
|
|
69
69
|
// The trailing hook's loading state — keep this on the LAST hook above.
|
|
70
|
-
isLoading:
|
|
70
|
+
isLoading: workspaceVolume.isLoading,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
@@ -12,6 +12,6 @@ export declare const genuiBadgeClass: (tone: BadgeTone) => string;
|
|
|
12
12
|
export declare function GenuiBadge({ props }: GenuiComponentProps): import("react").JSX.Element;
|
|
13
13
|
export declare function GenuiCallout({ props }: GenuiComponentProps): import("react").JSX.Element;
|
|
14
14
|
/** Set inside an image gallery (layout.tsx): the tile sizes the image, which covers it. A `tile` shows its caption on hover. */
|
|
15
|
-
export declare const GenuiImageGridContext: import("react").Context<false | "
|
|
15
|
+
export declare const GenuiImageGridContext: import("react").Context<false | "tile" | "lead">;
|
|
16
16
|
export declare function GenuiImage({ props }: GenuiComponentProps): import("react").JSX.Element;
|
|
17
17
|
export declare function GenuiLink({ props }: GenuiComponentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The form behind an own-app connect link (`/connect/app/[token]`): the app's
|
|
3
|
+
* client credentials and the store, for a Composio toolkit that runs on the
|
|
4
|
+
* customer's own app. Shopify is the one such app today.
|
|
5
|
+
*
|
|
6
|
+
* The page opens in the connect popup. The window that opened it polls the
|
|
7
|
+
* connection, so after a success this window only confirms and closes itself
|
|
8
|
+
* (or follows the native app's return link).
|
|
9
|
+
*/
|
|
10
|
+
export declare function AppCredentialsForm({ token }: {
|
|
11
|
+
token: string;
|
|
12
|
+
}): import("react").JSX.Element;
|