@kortix/ui 0.14.9 → 0.14.11
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 +55 -2
- package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
- package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
- package/dist/_vendor/shared/channel-message.d.ts +13 -2
- package/dist/_vendor/shared/index.d.ts +1 -0
- package/dist/_vendor/shared/runtime-versions.d.ts +9 -0
- package/dist/apps/app-preview-pool.js +19 -2
- package/dist/artifacts/artifact-frame.js +7 -3
- package/dist/customize/sections/component/channel-access-panel.js +4 -4
- package/dist/customize/sections/component/telegram-channel-row.js +7 -5
- package/dist/customize/sections/view/agent-editor-catalog.js +5 -0
- package/dist/customize/sections/view/channels-view.d.ts +2 -1
- package/dist/customize/sections/view/channels-view.js +12 -7
- package/dist/customize/settings/rail.js +9 -0
- package/dist/customize/settings/settings-tabs.d.ts +1 -1
- package/dist/customize/settings/settings-tabs.js +1 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
- package/dist/customize/settings/tabs/sandbox-template-form.js +8 -1
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +3 -3
- package/dist/customize/shared/catalog/catalog-empty-state.js +6 -4
- package/dist/files/renderers/image-frame.d.ts +3 -1
- package/dist/files/renderers/image-frame.js +2 -2
- package/dist/files/renderers/show-content-renderer.d.ts +2 -2
- package/dist/files/renderers/show-content-renderer.js +2 -1
- package/dist/i18n/en.d.ts +206 -0
- package/dist/i18n/en.js +219 -13
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +3 -3
- package/dist/internal/apps-and-extensions/apps-modal.d.ts +9 -0
- package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
- package/dist/internal/branding/branding-provider.js +3 -3
- package/dist/internal/chrome/browser-icon.d.ts +24 -0
- package/dist/internal/chrome/browser-icon.js +58 -0
- package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
- package/dist/internal/chrome/chrome-card-state.js +9 -0
- package/dist/internal/chrome/chrome-connect.d.ts +69 -0
- package/dist/internal/chrome/chrome-connect.js +178 -0
- package/dist/internal/chrome/chrome-mock.d.ts +4 -0
- package/dist/internal/chrome/chrome-mock.js +15 -0
- package/dist/internal/chrome/chrome-names.d.ts +15 -0
- package/dist/internal/chrome/chrome-names.js +35 -0
- package/dist/internal/chrome/extension.d.ts +47 -0
- package/dist/internal/chrome/extension.js +91 -0
- package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
- package/dist/internal/chrome/use-chrome-offered.js +22 -0
- package/dist/internal/connector-logo/connector-logo-source.d.ts +2 -1
- package/dist/internal/connector-logo/connector-logo-source.js +7 -6
- package/dist/internal/hooks/use-notification-center.d.ts +10 -6
- package/dist/internal/hooks/use-notification-center.js +32 -10
- package/dist/internal/icons/edge.d.ts +5 -0
- package/dist/internal/icons/edge.js +10 -0
- package/dist/internal/lib/browser-noise/rules/extensions.js +17 -3
- package/dist/internal/lib/detect-os.d.ts +43 -0
- package/dist/internal/lib/detect-os.js +70 -0
- package/dist/internal/lib/site-metadata.js +4 -4
- package/dist/internal/lib/use-project-feature-flags.js +5 -1
- package/dist/internal/notifications/notification-bell.js +4 -3
- package/dist/internal/notifications/notification-rows.d.ts +1 -1
- package/dist/internal/notifications/notification-rows.js +2 -0
- package/dist/internal/stores/apps-modal-store.d.ts +8 -0
- package/dist/internal/stores/apps-modal-store.js +6 -0
- package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
- package/dist/internal/stores/kortix-computer-store.d.ts +1 -1
- package/dist/markdown/setup-links/approval-decision.js +3 -1
- package/dist/primitives/empty-state.d.ts +2 -2
- package/dist/primitives/empty-state.js +6 -5
- package/dist/primitives/mermaid-renderer.js +1 -1
- package/dist/session/composer/send-stop-control.js +8 -3
- package/dist/session/header/session-site-header.js +3 -1
- package/dist/session/panel/easy/detail-view.js +4 -0
- package/dist/session/panel/mobile-tool-drawer.js +5 -3
- package/dist/session/panel/open-session-quick-view.js +2 -2
- package/dist/session/panel/panel-fallback.js +10 -7
- package/dist/session/panel/session-audit-shared.js +3 -1
- package/dist/session/panel/session-desktop.d.ts +6 -0
- package/dist/session/panel/session-desktop.js +74 -0
- package/dist/session/panel/session-panel-provider.d.ts +1 -0
- package/dist/session/panel/session-panel-provider.js +17 -1
- package/dist/session/panel/shared/use-panel-handoffs.d.ts +2 -2
- package/dist/session/panel/shared/use-panel-handoffs.js +5 -1
- package/dist/session/panel/use-session-panel-layout.js +8 -0
- package/dist/session/participants/session-participants.d.ts +3 -1
- package/dist/session/participants/session-participants.js +2 -2
- package/dist/session/prompts/approval-request.js +2 -0
- package/dist/session/status/session-tab-title.d.ts +1 -1
- package/dist/session/status/session-tab-title.js +1 -1
- package/dist/session/thread/session-chat.js +12 -0
- package/dist/session/thread/session-context-sub-sessions.js +1 -1
- package/dist/session/thread/session-thread.d.ts +13 -1
- package/dist/session/thread/session-thread.js +15 -5
- package/dist/session/thread/session-transcript-class.d.ts +5 -1
- package/dist/session/thread/session-transcript-class.js +5 -1
- package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
- package/dist/session/tool/tools/image-gen-tool.js +21 -11
- package/dist/session/turn/user-message.d.ts +7 -5
- package/dist/session/turn/user-message.js +14 -8
- package/dist/styles.css +1 -1
- package/dist/workspace/session-workspace.js +24 -5
- package/dist/workspace/sessions/session-label-badges.js +2 -1
- package/dist/workspace/sidebar/footer/project-chrome-nav.d.ts +10 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -0
- package/dist/workspace/sidebar/project-sidebar.js +5 -1
- package/package.json +43 -3
- package/skills/kortix-ui/references/modules.md +1 -1
|
@@ -6977,6 +6977,49 @@ function policySetNameError(name) {
|
|
|
6977
6977
|
return null;
|
|
6978
6978
|
}
|
|
6979
6979
|
|
|
6980
|
+
// ../shared/src/channel-descriptors.ts
|
|
6981
|
+
var CHANNEL_PLATFORM_IDS = ["slack", "teams", "email", "telegram"];
|
|
6982
|
+
var CHANNELS = {
|
|
6983
|
+
slack: {
|
|
6984
|
+
label: "Slack",
|
|
6985
|
+
envelope: "Slack",
|
|
6986
|
+
catalog: {
|
|
6987
|
+
domain: "slack.com",
|
|
6988
|
+
description: "Message the agent in Slack: mentions, DMs and channels, through the Kortix Slack app."
|
|
6989
|
+
}
|
|
6990
|
+
},
|
|
6991
|
+
teams: {
|
|
6992
|
+
label: "Microsoft Teams",
|
|
6993
|
+
envelope: "Teams",
|
|
6994
|
+
catalog: {
|
|
6995
|
+
domain: "teams.microsoft.com",
|
|
6996
|
+
description: "Message the agent in Microsoft Teams chats and channels, through the Kortix Teams app."
|
|
6997
|
+
},
|
|
6998
|
+
buttons: { max: 6 }
|
|
6999
|
+
},
|
|
7000
|
+
email: {
|
|
7001
|
+
label: "Email",
|
|
7002
|
+
envelope: "Email",
|
|
7003
|
+
catalog: { domain: "email.kortix", description: "Give the project an inbox: people email the agent and it replies." }
|
|
7004
|
+
},
|
|
7005
|
+
telegram: {
|
|
7006
|
+
label: "Telegram",
|
|
7007
|
+
envelope: "Telegram",
|
|
7008
|
+
catalog: { domain: "telegram.org", description: "Message the agent from Telegram through a bot you own." },
|
|
7009
|
+
messageChars: 4096,
|
|
7010
|
+
buttons: { max: 6, dataBytes: 64 },
|
|
7011
|
+
// A bot token is `<bot id>:<secret>`.
|
|
7012
|
+
connect: { tokenPattern: /^\d{5,15}:[A-Za-z0-9_-]{30,64}$/, tokenPlaceholder: "123456789:\u2026" },
|
|
7013
|
+
access: {
|
|
7014
|
+
userId: /^\d{1,20}$/,
|
|
7015
|
+
idPlaceholder: "123456789",
|
|
7016
|
+
idsPlaceholder: "123456789, 987654321",
|
|
7017
|
+
idInputMode: "numeric"
|
|
7018
|
+
}
|
|
7019
|
+
}
|
|
7020
|
+
};
|
|
7021
|
+
var isChannelPlatform = (platform) => CHANNEL_PLATFORM_IDS.includes(platform);
|
|
7022
|
+
|
|
6980
7023
|
// ../manifest-schema/src/slug.ts
|
|
6981
7024
|
var SLUG_MAX_LENGTH = 128;
|
|
6982
7025
|
function trimSeparators(value) {
|
|
@@ -8623,7 +8666,7 @@ function readSlackFollowUpHeader(line) {
|
|
|
8623
8666
|
}
|
|
8624
8667
|
|
|
8625
8668
|
// ../shared/src/channel-message.ts
|
|
8626
|
-
var CHANNEL_PLATFORMS =
|
|
8669
|
+
var CHANNEL_PLATFORMS = CHANNEL_PLATFORM_IDS.map((id) => CHANNELS[id].envelope);
|
|
8627
8670
|
var TAIL_MARKERS = [
|
|
8628
8671
|
/^How to work:/m,
|
|
8629
8672
|
/^Attached files \(download with/m,
|
|
@@ -8782,6 +8825,16 @@ function parseChannelMessage(rawText) {
|
|
|
8782
8825
|
}
|
|
8783
8826
|
return void 0;
|
|
8784
8827
|
}
|
|
8828
|
+
function channelPromptTail(text, platform) {
|
|
8829
|
+
const at = text.lastIndexOf(`
|
|
8830
|
+
\u2500\u2500 ${platform} instructions
|
|
8831
|
+
`);
|
|
8832
|
+
return at < 0 ? "" : text.slice(at);
|
|
8833
|
+
}
|
|
8834
|
+
function isChannelFileLabel(text) {
|
|
8835
|
+
const line = text.trim();
|
|
8836
|
+
return line.length > 2 && line.startsWith("(") && line.endsWith(")") && !/[()\n]/.test(line.slice(1, -1));
|
|
8837
|
+
}
|
|
8785
8838
|
|
|
8786
8839
|
// ../shared/src/chat-mention.ts
|
|
8787
8840
|
function stripChatMentionMarkup(value) {
|
|
@@ -11003,4 +11056,4 @@ smol-toml/dist/index.js:
|
|
|
11003
11056
|
*)
|
|
11004
11057
|
*/
|
|
11005
11058
|
|
|
11006
|
-
export { AVATAR_INK, CARD_TEXT_RATIO, COMMIT_CONFIRM_ATTEMPTS, COMMIT_CONFIRM_DELAY_MS, CREDITS_PER_DOLLAR, CURATED_SECTIONS, KATEX_FENCE_LANGUAGES, LANGUAGE_ALIASES, MAX_PROMPT_ATTACHMENTS_BYTES, MAX_PROMPT_ATTACHMENT_BYTES, MAX_PROMPT_ATTACHMENT_FILES, MAX_PROMPT_UPLOAD_FILENAME_BYTES, META_AGENT_DISPLAY_NAME, META_SANDBOX_SLUG, OTHER, PASTED_INLINE_MAX_BYTES, POLICY_SETS_UNSUPPORTED_PROVIDERS, POPULAR_SECTION, PREVIEW_BUILDING_STATES, PREVIEW_STATE_MESSAGE, PROJECT_GLYPH_COLORS, PROJECT_GLYPH_NAMES, UNKNOWN_RATIO, UPLOAD_LIMITS, appAdminsOnly, autoLinkUrls, avatarFill, buildWebhookSampleRequest, capitalizeWords, cardImageShape, cardListLayout, chalkColors, confirmCommitted, countInSection, dollarsToCredits, editConfigPrompt, errorCode, escapeCurrencyDollars, expandPastedContent, extractReadableHtml, fileTagBlocks, formatFileSize, formatRelative, formatUsdAsCredits, gridApps, groupIntoSections, hasReferenceDefinitionOutsideFences, humanizeCategory, indexOfIgnoreCase, isAllowedWebPushHost, isAmbiguousCreateFailure, isMermaidCode, isMetaAgentName, languageLabel, looksLikeMarkdown, masonryColumns, neutralizePastedTags, newConfigPrompt, newPastedContentId, normalizeLanguage, normalizeLatexDelimiters, openMarkdownLinkAtEnd, parseBackgroundWorkers, parseBalanceUsd, parseChannelMessage, parseGrepOutput, parseManifestText, parseMemoryEntryOutput, parseMemorySearchOutput, parseReminderPrompt, parseRoomDigest, parseRoomPrompt, parseSessionGetOutput, parseSessionMessagesOutput, parseSessionMetadataOutput, parseSessionSearchHits, parseTriggerEvent, parseTriggerLines, policySetNameError, prefersPreviewLink, prepareMarkdownForKatex, prepareMarkdownForMath, promptFileReferenceXml, ptyOutputBlock, ptySpawnedBody, pushTypeOf, referenceHeaders, removeSpans, replaceSpans, resolveRegisteredKey, safeHttpUrl, sandboxMediaPath, sanitizePromptUploadFilename, sectionKeyForCategory, sectionKeysForEntry, sectionTitle, selfClosingTags, serializePromptWithPastes, shouldTilePaste, skillDocumentBody, slackPlainText, slugifySlug, spaceSlug, splitPastedContent, stripBashMetadata, stripChatMentionMarkup, stripMarkupForToolOutput, tagBlocks, toolRegistryCandidates, trimPastedText, truncateString, utf8Bytes, withoutEdgeQuotes, xmlBlocks };
|
|
11059
|
+
export { AVATAR_INK, CARD_TEXT_RATIO, CHANNELS, CHANNEL_PLATFORM_IDS, COMMIT_CONFIRM_ATTEMPTS, COMMIT_CONFIRM_DELAY_MS, CREDITS_PER_DOLLAR, CURATED_SECTIONS, KATEX_FENCE_LANGUAGES, LANGUAGE_ALIASES, MAX_PROMPT_ATTACHMENTS_BYTES, MAX_PROMPT_ATTACHMENT_BYTES, MAX_PROMPT_ATTACHMENT_FILES, MAX_PROMPT_UPLOAD_FILENAME_BYTES, META_AGENT_DISPLAY_NAME, META_SANDBOX_SLUG, OTHER, PASTED_INLINE_MAX_BYTES, POLICY_SETS_UNSUPPORTED_PROVIDERS, POPULAR_SECTION, PREVIEW_BUILDING_STATES, PREVIEW_STATE_MESSAGE, PROJECT_GLYPH_COLORS, PROJECT_GLYPH_NAMES, UNKNOWN_RATIO, UPLOAD_LIMITS, appAdminsOnly, autoLinkUrls, avatarFill, buildWebhookSampleRequest, capitalizeWords, cardImageShape, cardListLayout, chalkColors, channelPromptTail, confirmCommitted, countInSection, dollarsToCredits, editConfigPrompt, errorCode, escapeCurrencyDollars, expandPastedContent, extractReadableHtml, fileTagBlocks, formatFileSize, formatRelative, formatUsdAsCredits, gridApps, groupIntoSections, hasReferenceDefinitionOutsideFences, humanizeCategory, indexOfIgnoreCase, isAllowedWebPushHost, isAmbiguousCreateFailure, isChannelFileLabel, isChannelPlatform, isMermaidCode, isMetaAgentName, languageLabel, looksLikeMarkdown, masonryColumns, neutralizePastedTags, newConfigPrompt, newPastedContentId, normalizeLanguage, normalizeLatexDelimiters, openMarkdownLinkAtEnd, parseBackgroundWorkers, parseBalanceUsd, parseChannelMessage, parseGrepOutput, parseManifestText, parseMemoryEntryOutput, parseMemorySearchOutput, parseReminderPrompt, parseRoomDigest, parseRoomPrompt, parseSessionGetOutput, parseSessionMessagesOutput, parseSessionMetadataOutput, parseSessionSearchHits, parseTriggerEvent, parseTriggerLines, policySetNameError, prefersPreviewLink, prepareMarkdownForKatex, prepareMarkdownForMath, promptFileReferenceXml, ptyOutputBlock, ptySpawnedBody, pushTypeOf, referenceHeaders, removeSpans, replaceSpans, resolveRegisteredKey, safeHttpUrl, sandboxMediaPath, sanitizePromptUploadFilename, sectionKeyForCategory, sectionKeysForEntry, sectionTitle, selfClosingTags, serializePromptWithPastes, shouldTilePaste, skillDocumentBody, slackPlainText, slugifySlug, spaceSlug, splitPastedContent, stripBashMetadata, stripChatMentionMarkup, stripMarkupForToolOutput, tagBlocks, toolRegistryCandidates, trimPastedText, truncateString, utf8Bytes, withoutEdgeQuotes, xmlBlocks };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const artifactCommentAnchorSchema: z.ZodEffects<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
3
|
+
type: z.ZodLiteral<"text">;
|
|
4
|
+
version: z.ZodString;
|
|
5
|
+
quote: z.ZodString;
|
|
6
|
+
prefix: z.ZodString;
|
|
7
|
+
suffix: z.ZodString;
|
|
8
|
+
}, "strict", z.ZodTypeAny, {
|
|
9
|
+
type: "text";
|
|
10
|
+
version: string;
|
|
11
|
+
quote: string;
|
|
12
|
+
prefix: string;
|
|
13
|
+
suffix: string;
|
|
14
|
+
}, {
|
|
15
|
+
type: "text";
|
|
16
|
+
version: string;
|
|
17
|
+
quote: string;
|
|
18
|
+
prefix: string;
|
|
19
|
+
suffix: string;
|
|
20
|
+
}>, z.ZodObject<{
|
|
21
|
+
offset: z.ZodObject<{
|
|
22
|
+
x: z.ZodNumber;
|
|
23
|
+
y: z.ZodNumber;
|
|
24
|
+
}, "strict", z.ZodTypeAny, {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}, {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}>;
|
|
31
|
+
version: z.ZodString;
|
|
32
|
+
selector: z.ZodString;
|
|
33
|
+
snippet: z.ZodString;
|
|
34
|
+
viewport_width: z.ZodNumber;
|
|
35
|
+
scroll: z.ZodObject<{
|
|
36
|
+
x: z.ZodNumber;
|
|
37
|
+
y: z.ZodNumber;
|
|
38
|
+
}, "strict", z.ZodTypeAny, {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
}, {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
}>;
|
|
45
|
+
type: z.ZodLiteral<"point">;
|
|
46
|
+
}, "strict", z.ZodTypeAny, {
|
|
47
|
+
type: "point";
|
|
48
|
+
version: string;
|
|
49
|
+
offset: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
};
|
|
53
|
+
selector: string;
|
|
54
|
+
snippet: string;
|
|
55
|
+
viewport_width: number;
|
|
56
|
+
scroll: {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
};
|
|
60
|
+
}, {
|
|
61
|
+
type: "point";
|
|
62
|
+
version: string;
|
|
63
|
+
offset: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
};
|
|
67
|
+
selector: string;
|
|
68
|
+
snippet: string;
|
|
69
|
+
viewport_width: number;
|
|
70
|
+
scroll: {
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
};
|
|
74
|
+
}>, z.ZodObject<{
|
|
75
|
+
offset: z.ZodObject<{
|
|
76
|
+
x: z.ZodNumber;
|
|
77
|
+
y: z.ZodNumber;
|
|
78
|
+
width: z.ZodNumber;
|
|
79
|
+
height: z.ZodNumber;
|
|
80
|
+
}, "strict", z.ZodTypeAny, {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
width: number;
|
|
84
|
+
height: number;
|
|
85
|
+
}, {
|
|
86
|
+
x: number;
|
|
87
|
+
y: number;
|
|
88
|
+
width: number;
|
|
89
|
+
height: number;
|
|
90
|
+
}>;
|
|
91
|
+
version: z.ZodString;
|
|
92
|
+
selector: z.ZodString;
|
|
93
|
+
snippet: z.ZodString;
|
|
94
|
+
viewport_width: z.ZodNumber;
|
|
95
|
+
scroll: z.ZodObject<{
|
|
96
|
+
x: z.ZodNumber;
|
|
97
|
+
y: z.ZodNumber;
|
|
98
|
+
}, "strict", z.ZodTypeAny, {
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
}, {
|
|
102
|
+
x: number;
|
|
103
|
+
y: number;
|
|
104
|
+
}>;
|
|
105
|
+
type: z.ZodLiteral<"region">;
|
|
106
|
+
}, "strict", z.ZodTypeAny, {
|
|
107
|
+
type: "region";
|
|
108
|
+
version: string;
|
|
109
|
+
offset: {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
width: number;
|
|
113
|
+
height: number;
|
|
114
|
+
};
|
|
115
|
+
selector: string;
|
|
116
|
+
snippet: string;
|
|
117
|
+
viewport_width: number;
|
|
118
|
+
scroll: {
|
|
119
|
+
x: number;
|
|
120
|
+
y: number;
|
|
121
|
+
};
|
|
122
|
+
}, {
|
|
123
|
+
type: "region";
|
|
124
|
+
version: string;
|
|
125
|
+
offset: {
|
|
126
|
+
x: number;
|
|
127
|
+
y: number;
|
|
128
|
+
width: number;
|
|
129
|
+
height: number;
|
|
130
|
+
};
|
|
131
|
+
selector: string;
|
|
132
|
+
snippet: string;
|
|
133
|
+
viewport_width: number;
|
|
134
|
+
scroll: {
|
|
135
|
+
x: number;
|
|
136
|
+
y: number;
|
|
137
|
+
};
|
|
138
|
+
}>, z.ZodObject<{
|
|
139
|
+
type: z.ZodLiteral<"none">;
|
|
140
|
+
version: z.ZodString;
|
|
141
|
+
}, "strict", z.ZodTypeAny, {
|
|
142
|
+
type: "none";
|
|
143
|
+
version: string;
|
|
144
|
+
}, {
|
|
145
|
+
type: "none";
|
|
146
|
+
version: string;
|
|
147
|
+
}>]>, {
|
|
148
|
+
type: "text";
|
|
149
|
+
version: string;
|
|
150
|
+
quote: string;
|
|
151
|
+
prefix: string;
|
|
152
|
+
suffix: string;
|
|
153
|
+
} | {
|
|
154
|
+
type: "point";
|
|
155
|
+
version: string;
|
|
156
|
+
offset: {
|
|
157
|
+
x: number;
|
|
158
|
+
y: number;
|
|
159
|
+
};
|
|
160
|
+
selector: string;
|
|
161
|
+
snippet: string;
|
|
162
|
+
viewport_width: number;
|
|
163
|
+
scroll: {
|
|
164
|
+
x: number;
|
|
165
|
+
y: number;
|
|
166
|
+
};
|
|
167
|
+
} | {
|
|
168
|
+
type: "region";
|
|
169
|
+
version: string;
|
|
170
|
+
offset: {
|
|
171
|
+
x: number;
|
|
172
|
+
y: number;
|
|
173
|
+
width: number;
|
|
174
|
+
height: number;
|
|
175
|
+
};
|
|
176
|
+
selector: string;
|
|
177
|
+
snippet: string;
|
|
178
|
+
viewport_width: number;
|
|
179
|
+
scroll: {
|
|
180
|
+
x: number;
|
|
181
|
+
y: number;
|
|
182
|
+
};
|
|
183
|
+
} | {
|
|
184
|
+
type: "none";
|
|
185
|
+
version: string;
|
|
186
|
+
}, {
|
|
187
|
+
type: "text";
|
|
188
|
+
version: string;
|
|
189
|
+
quote: string;
|
|
190
|
+
prefix: string;
|
|
191
|
+
suffix: string;
|
|
192
|
+
} | {
|
|
193
|
+
type: "point";
|
|
194
|
+
version: string;
|
|
195
|
+
offset: {
|
|
196
|
+
x: number;
|
|
197
|
+
y: number;
|
|
198
|
+
};
|
|
199
|
+
selector: string;
|
|
200
|
+
snippet: string;
|
|
201
|
+
viewport_width: number;
|
|
202
|
+
scroll: {
|
|
203
|
+
x: number;
|
|
204
|
+
y: number;
|
|
205
|
+
};
|
|
206
|
+
} | {
|
|
207
|
+
type: "region";
|
|
208
|
+
version: string;
|
|
209
|
+
offset: {
|
|
210
|
+
x: number;
|
|
211
|
+
y: number;
|
|
212
|
+
width: number;
|
|
213
|
+
height: number;
|
|
214
|
+
};
|
|
215
|
+
selector: string;
|
|
216
|
+
snippet: string;
|
|
217
|
+
viewport_width: number;
|
|
218
|
+
scroll: {
|
|
219
|
+
x: number;
|
|
220
|
+
y: number;
|
|
221
|
+
};
|
|
222
|
+
} | {
|
|
223
|
+
type: "none";
|
|
224
|
+
version: string;
|
|
225
|
+
}>;
|
|
226
|
+
export type ArtifactCommentAnchor = z.infer<typeof artifactCommentAnchorSchema>;
|
|
227
|
+
export type ArtifactTextAnchor = Extract<ArtifactCommentAnchor, {
|
|
228
|
+
type: 'text';
|
|
229
|
+
}>;
|
|
230
|
+
export type ArtifactTextPosition = {
|
|
231
|
+
start: number | null;
|
|
232
|
+
end: number | null;
|
|
233
|
+
outdated: boolean;
|
|
234
|
+
};
|
|
235
|
+
export declare function reanchorArtifactText(text: string, anchor: ArtifactTextAnchor): ArtifactTextPosition;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One descriptor per chat channel: the facts the API, the manifest schema and
|
|
3
|
+
* the web read instead of repeating them. To add a channel, add its id and its
|
|
4
|
+
* descriptor here; `tsc` then names every record that needs a value for it.
|
|
5
|
+
*
|
|
6
|
+
* No imports, so the dependency-free manifest constants can read it. Not in the
|
|
7
|
+
* package root: `channel-message.ts` already exports `CHANNEL_PLATFORMS` there.
|
|
8
|
+
*/
|
|
9
|
+
/** The `platform` of a `channel` connector. The order is the manifest schema's enum order. */
|
|
10
|
+
export declare const CHANNEL_PLATFORM_IDS: readonly ["slack", "teams", "email", "telegram"];
|
|
11
|
+
export type ChannelPlatformId = (typeof CHANNEL_PLATFORM_IDS)[number];
|
|
12
|
+
export interface ChannelDescriptor {
|
|
13
|
+
/** The display name. */
|
|
14
|
+
label: string;
|
|
15
|
+
/** The platform word of a prompt header, `[<envelope> · …]`. Transcripts store it: never rename one. */
|
|
16
|
+
envelope: string;
|
|
17
|
+
/** The `native:<id>` catalog card. Its icon is `/connector-icons/<id>.svg`. */
|
|
18
|
+
catalog: {
|
|
19
|
+
domain: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
/** The most characters one message holds. */
|
|
23
|
+
messageChars?: number;
|
|
24
|
+
/** One tap per option up to `max` options. `dataBytes`: the platform's cap on a button's data. */
|
|
25
|
+
buttons?: {
|
|
26
|
+
max: number;
|
|
27
|
+
dataBytes?: number;
|
|
28
|
+
};
|
|
29
|
+
/** The token a person pastes to connect. */
|
|
30
|
+
connect?: {
|
|
31
|
+
tokenPattern: RegExp;
|
|
32
|
+
tokenPlaceholder: string;
|
|
33
|
+
};
|
|
34
|
+
/** Senders pass an allow-list of these user ids. */
|
|
35
|
+
access?: {
|
|
36
|
+
userId: RegExp;
|
|
37
|
+
idPlaceholder: string;
|
|
38
|
+
idsPlaceholder: string;
|
|
39
|
+
idInputMode: 'numeric' | 'text';
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export declare const CHANNELS: {
|
|
43
|
+
readonly slack: {
|
|
44
|
+
readonly label: "Slack";
|
|
45
|
+
readonly envelope: "Slack";
|
|
46
|
+
readonly catalog: {
|
|
47
|
+
readonly domain: "slack.com";
|
|
48
|
+
readonly description: "Message the agent in Slack: mentions, DMs and channels, through the Kortix Slack app.";
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
readonly teams: {
|
|
52
|
+
readonly label: "Microsoft Teams";
|
|
53
|
+
readonly envelope: "Teams";
|
|
54
|
+
readonly catalog: {
|
|
55
|
+
readonly domain: "teams.microsoft.com";
|
|
56
|
+
readonly description: "Message the agent in Microsoft Teams chats and channels, through the Kortix Teams app.";
|
|
57
|
+
};
|
|
58
|
+
readonly buttons: {
|
|
59
|
+
readonly max: 6;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
readonly email: {
|
|
63
|
+
readonly label: "Email";
|
|
64
|
+
readonly envelope: "Email";
|
|
65
|
+
readonly catalog: {
|
|
66
|
+
readonly domain: "email.kortix";
|
|
67
|
+
readonly description: "Give the project an inbox: people email the agent and it replies.";
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
readonly telegram: {
|
|
71
|
+
readonly label: "Telegram";
|
|
72
|
+
readonly envelope: "Telegram";
|
|
73
|
+
readonly catalog: {
|
|
74
|
+
readonly domain: "telegram.org";
|
|
75
|
+
readonly description: "Message the agent from Telegram through a bot you own.";
|
|
76
|
+
};
|
|
77
|
+
readonly messageChars: 4096;
|
|
78
|
+
readonly buttons: {
|
|
79
|
+
readonly max: 6;
|
|
80
|
+
readonly dataBytes: 64;
|
|
81
|
+
};
|
|
82
|
+
readonly connect: {
|
|
83
|
+
readonly tokenPattern: RegExp;
|
|
84
|
+
readonly tokenPlaceholder: "123456789:…";
|
|
85
|
+
};
|
|
86
|
+
readonly access: {
|
|
87
|
+
readonly userId: RegExp;
|
|
88
|
+
readonly idPlaceholder: "123456789";
|
|
89
|
+
readonly idsPlaceholder: "123456789, 987654321";
|
|
90
|
+
readonly idInputMode: "numeric";
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
/** The reserved slug a channel's built-in connector uses, so a user connector cannot take it. */
|
|
95
|
+
export declare const channelConnectorSlug: <P extends ChannelPlatformId>(platform: P) => `kortix_${P}`;
|
|
96
|
+
export declare const isChannelPlatform: (platform: string) => platform is ChannelPlatformId;
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
* attempt. The pre-2026 header regex and the `<at>` strip did: 240k characters
|
|
30
30
|
* took 22 s and 7 s.
|
|
31
31
|
*/
|
|
32
|
-
/** The platform words a header names
|
|
33
|
-
export declare const CHANNEL_PLATFORMS:
|
|
32
|
+
/** The platform words a header names: each channel descriptor's `envelope`. Any other word reads as Slack, as every deployed build reads it. */
|
|
33
|
+
export declare const CHANNEL_PLATFORMS: ("Slack" | "Teams" | "Email" | "Telegram")[];
|
|
34
34
|
export type ChannelPlatform = (typeof CHANNEL_PLATFORMS)[number];
|
|
35
35
|
export interface ChannelMessageInfo {
|
|
36
36
|
platform: ChannelPlatform;
|
|
@@ -42,6 +42,17 @@ export interface ChannelMessageInfo {
|
|
|
42
42
|
followUp: boolean;
|
|
43
43
|
}
|
|
44
44
|
export declare function parseChannelMessage(rawText: string | null | undefined): ChannelMessageInfo | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* The lines Kortix wrote in a `channelPromptText` prompt: from its last `── <Platform> instructions`
|
|
47
|
+
* line on, where the channel core also puts each file's `<file>` tag. Empty for an older shape. A
|
|
48
|
+
* `<file>` tag before that line is in the sender's text, so it is text, not a file.
|
|
49
|
+
*/
|
|
50
|
+
export declare function channelPromptTail(text: string, platform: ChannelPlatform): string;
|
|
51
|
+
/**
|
|
52
|
+
* True when the sender's text is only the label an adapter writes for a file sent with no caption
|
|
53
|
+
* (`(photo)`, `(file q3.pdf)`, `(voice message, 7 s)`). A view that draws the file hides it.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isChannelFileLabel(text: string): boolean;
|
|
45
56
|
/** What a channel adapter knows about one incoming message; `channelPromptText` writes it. */
|
|
46
57
|
export interface ChannelEnvelope {
|
|
47
58
|
platform: ChannelPlatform;
|
|
@@ -19,6 +19,10 @@ export type RuntimeVersions = {
|
|
|
19
19
|
agentBrowser: string;
|
|
20
20
|
playwright: string;
|
|
21
21
|
anydoc: string;
|
|
22
|
+
/** tembo/voxl commit the sandbox desktop streamer is built from (apps/sandbox/voxl/release.sh). */
|
|
23
|
+
voxl: string;
|
|
24
|
+
voxlSha256Amd64: string;
|
|
25
|
+
voxlSha256Arm64: string;
|
|
22
26
|
/** pi packages every pi session loads, as pi sources: `npm:<name>@<exact version>`. */
|
|
23
27
|
piSystemPackages: string[];
|
|
24
28
|
};
|
|
@@ -45,6 +49,11 @@ export declare const OPENCODE_USER_AGENT: string;
|
|
|
45
49
|
export declare const AGENT_BROWSER_VERSION: string;
|
|
46
50
|
export declare const PLAYWRIGHT_VERSION: string;
|
|
47
51
|
export declare const ANYDOC_VERSION: string;
|
|
52
|
+
export declare const VOXL_VERSION: string;
|
|
53
|
+
export declare const VOXL_SHA256_AMD64: string;
|
|
54
|
+
export declare const VOXL_SHA256_ARM64: string;
|
|
55
|
+
/** The GitHub release apps/sandbox/voxl/release.sh publishes for VOXL_VERSION. */
|
|
56
|
+
export declare const VOXL_RELEASE_URL: string;
|
|
48
57
|
/** Throws unless `source` is an exact `npm:<name>@<x.y.z>` pin. */
|
|
49
58
|
export declare function assertPiSystemPackage(source: string): void;
|
|
50
59
|
/**
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* parked off screen. A card or the big view CLAIMS it: the frame moves into
|
|
10
10
|
* that slot with `Element.moveBefore`, which keeps the document alive. The
|
|
11
11
|
* newest claim wins; releasing hands it back to the previous claim, else to
|
|
12
|
-
* the parking lot.
|
|
12
|
+
* the parking lot. A release lands at the end of the task: a release and a
|
|
13
|
+
* claim in one React commit (a Strict Mode remount, a page handing the frame
|
|
14
|
+
* to the next) leave the frame where it is or move it once, never through the
|
|
15
|
+
* parking lot, whose different size makes the page lay out (and flash) twice. Without `moveBefore` (older browsers) the move reloads the
|
|
13
16
|
* frame — the old behavior — and nothing is preloaded.
|
|
14
17
|
*
|
|
15
18
|
* The frame's `src` is set once. A refetched access session mints a new URL
|
|
@@ -108,9 +111,23 @@ export function claimFrame(key, slot, placement) {
|
|
|
108
111
|
return () => {
|
|
109
112
|
entry.claims = entry.claims.filter((item) => item !== claim);
|
|
110
113
|
if (entries.get(key) === entry)
|
|
111
|
-
|
|
114
|
+
placeAfterTask(entry);
|
|
112
115
|
};
|
|
113
116
|
}
|
|
117
|
+
// Entries whose claims changed by a release, placed once the current task ends.
|
|
118
|
+
const releasing = new Set();
|
|
119
|
+
function placeAfterTask(entry) {
|
|
120
|
+
if (releasing.size === 0) {
|
|
121
|
+
queueMicrotask(() => {
|
|
122
|
+
const due = [...releasing];
|
|
123
|
+
releasing.clear();
|
|
124
|
+
for (const item of due)
|
|
125
|
+
if (entries.get(item.frame.dataset.frameKey ?? '') === item)
|
|
126
|
+
place(item);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
releasing.add(entry);
|
|
130
|
+
}
|
|
114
131
|
/** Restyle the current claim of `slot` (a card's scale changes as it is measured). */
|
|
115
132
|
export function restyleFrame(key, slot, placement) {
|
|
116
133
|
const entry = entries.get(key);
|
|
@@ -4,10 +4,14 @@ import { forwardRef, useLayoutEffect, useState } from 'react';
|
|
|
4
4
|
import { claimFrame, ensureFrame } from '../apps/app-preview-pool.js';
|
|
5
5
|
import { ARTIFACT_FRAME_ALLOW, ARTIFACT_IFRAME_SANDBOX } from './frame-policy.js';
|
|
6
6
|
/**
|
|
7
|
-
* The frame's canvas:
|
|
8
|
-
*
|
|
7
|
+
* The frame's canvas: what shows where the page has not painted yet. Open, a
|
|
8
|
+
* third-party page with no background of its own reads as a white page, as it
|
|
9
|
+
* would in a browser tab, in both themes. As a card preview it is the app's
|
|
10
|
+
* background: a preview that is still painting (on load, on a tab switch)
|
|
11
|
+
* must not flash white in the dark theme.
|
|
9
12
|
*/
|
|
10
13
|
const ARTIFACT_CANVAS = 'bg-white';
|
|
14
|
+
const PREVIEW_CANVAS = 'bg-background';
|
|
11
15
|
/**
|
|
12
16
|
* An artifact page. The frame lives in the project's frame pool
|
|
13
17
|
* (`@kortix/ui/apps`, shared with App previews): it loads once, in the
|
|
@@ -18,7 +22,7 @@ const ARTIFACT_CANVAS = 'bg-white';
|
|
|
18
22
|
export const ArtifactFrame = forwardRef(function ArtifactFrame({ frameKey, src, title, className, preview }, ref) {
|
|
19
23
|
const [slot, setSlot] = useState(null);
|
|
20
24
|
const interactive = !preview;
|
|
21
|
-
const frameClass = `${className ?? ''} ${ARTIFACT_CANVAS}`;
|
|
25
|
+
const frameClass = `${className ?? ''} ${preview ? PREVIEW_CANVAS : ARTIFACT_CANVAS}`;
|
|
22
26
|
useLayoutEffect(() => {
|
|
23
27
|
if (!slot)
|
|
24
28
|
return;
|
|
@@ -23,18 +23,18 @@ import { errorToast } from '../../../primitives/toast.js';
|
|
|
23
23
|
import { UserAvatar } from '../../../primitives/user-avatar.js';
|
|
24
24
|
import { useAllowChannelUser, useChannelUserPhoto, useChannelUsers, useDismissChannelAccessRequest, useRemoveChannelUser, } from '../../../internal/hooks/channels/use-channels-installations.js';
|
|
25
25
|
import { useTranslations } from '../../../i18n/index.js';
|
|
26
|
+
import { CHANNELS } from '../../../_vendor/kortix-shared.js';
|
|
26
27
|
import { UsersIcon } from '@phosphor-icons/react';
|
|
27
28
|
import { useEffect, useId, useRef, useState } from 'react';
|
|
28
29
|
/** What differs per platform. The `copy` values are `connectorPages` keys. */
|
|
29
30
|
export const CHANNEL_ACCESS = {
|
|
30
31
|
telegram: {
|
|
31
|
-
// Digits only.
|
|
32
32
|
parseUserId: (raw) => {
|
|
33
33
|
const id = raw.trim();
|
|
34
|
-
return
|
|
34
|
+
return CHANNELS.telegram.access.userId.test(id) ? id : null;
|
|
35
35
|
},
|
|
36
|
-
idPlaceholder:
|
|
37
|
-
idInputMode:
|
|
36
|
+
idPlaceholder: CHANNELS.telegram.access.idPlaceholder,
|
|
37
|
+
idInputMode: CHANNELS.telegram.access.idInputMode,
|
|
38
38
|
copy: {
|
|
39
39
|
descriptionKey: 'telegramUsersDescription',
|
|
40
40
|
emptyDescription: 'telegramUsersEmptyDescription',
|
|
@@ -18,11 +18,13 @@ import { ChannelDisconnectButton, ChannelRow, } from './channel-row.js';
|
|
|
18
18
|
import { ChannelAccessPanel } from './channel-access-panel.js';
|
|
19
19
|
import { useConnectTelegram, useDisconnectTelegram, useTelegramInstall, } from '../../../internal/hooks/channels/use-channels-installations.js';
|
|
20
20
|
import { useTranslations } from '../../../i18n/index.js';
|
|
21
|
+
import { CHANNELS } from '../../../_vendor/kortix-shared.js';
|
|
21
22
|
import { useState } from 'react';
|
|
23
|
+
const TELEGRAM = CHANNELS.telegram;
|
|
22
24
|
/** "1, 2 3" → ["1","2","3"]; null when any entry is not a number. */
|
|
23
25
|
export function parseTelegramUserIds(raw) {
|
|
24
26
|
const ids = raw.split(/[\s,]+/).filter(Boolean);
|
|
25
|
-
return ids.every((id) =>
|
|
27
|
+
return ids.every((id) => TELEGRAM.access.userId.test(id)) ? ids : null;
|
|
26
28
|
}
|
|
27
29
|
export function TelegramChannelRow({ projectId, canWrite }) {
|
|
28
30
|
const t = useTranslations('hardcodedUi.i18nComplete');
|
|
@@ -30,9 +32,9 @@ export function TelegramChannelRow({ projectId, canWrite }) {
|
|
|
30
32
|
const { data: install } = useTelegramInstall(projectId);
|
|
31
33
|
const disconnect = useDisconnectTelegram();
|
|
32
34
|
const [dialog, setDialog] = useState(null);
|
|
33
|
-
return (_jsxs(_Fragment, { children: [_jsx(ChannelRow, { app: "telegram", name:
|
|
35
|
+
return (_jsxs(_Fragment, { children: [_jsx(ChannelRow, { app: "telegram", name: TELEGRAM.label, connected: Boolean(install), detail: install?.username ? `@${install.username}` : null, hero: {
|
|
34
36
|
title: tPages('telegramHeroTitle'),
|
|
35
|
-
connectedTitle: tPages('channelConnectedTitle', { name:
|
|
37
|
+
connectedTitle: tPages('channelConnectedTitle', { name: TELEGRAM.label }),
|
|
36
38
|
...(install ? {} : { lede: tPages('telegramHeroLede') }),
|
|
37
39
|
preview: _jsx(TelegramChatMock, {}),
|
|
38
40
|
}, pitch: t.raw('text51e6bc656528'), actions: !canWrite ? null : install ? (_jsxs(_Fragment, { children: [_jsxs(Button, { size: "sm", variant: "ghost", onClick: () => setDialog('users'), children: [t.raw('text2c3059c25723'), install.access_request_count ? (_jsx(CountBadge, { count: install.access_request_count, tone: "waiting" })) : null] }), _jsx(ChannelDisconnectButton, { pending: disconnect.isPending, onConfirm: (done) => disconnect.mutate(projectId, {
|
|
@@ -60,9 +62,9 @@ function TelegramConnectForm({ projectId, onDone }) {
|
|
|
60
62
|
},
|
|
61
63
|
onError: (error) => errorToast(error.message),
|
|
62
64
|
});
|
|
63
|
-
}, children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t.raw('text00c7991f0490') }), _jsx(ModalDescription, { children: t.raw('texta832efd235a7') })] }), _jsx(ModalBody, { children: _jsxs(FieldGroup, { children: [_jsxs(Field, { children: [_jsx(FieldTitle, { children: t.raw('text5bb9aecca021') }), _jsx(Input, { type: "password", autoComplete: "off", placeholder:
|
|
65
|
+
}, children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t.raw('text00c7991f0490') }), _jsx(ModalDescription, { children: t.raw('texta832efd235a7') })] }), _jsx(ModalBody, { children: _jsxs(FieldGroup, { children: [_jsxs(Field, { children: [_jsx(FieldTitle, { children: t.raw('text5bb9aecca021') }), _jsx(Input, { type: "password", autoComplete: "off", placeholder: TELEGRAM.connect.tokenPlaceholder, value: token, onChange: (event) => setToken(event.target.value) })] }), _jsx(TelegramUsersField, { value: users, onChange: setUsers, invalid: !ids })] }) }), _jsxs(ModalFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: onDone, children: t.raw('text19766ed6ccb2') }), _jsxs(Button, { type: "submit", disabled: !token.trim() || !ids || connect.isPending, children: [connect.isPending ? _jsx(Loading, { className: "size-3.5 shrink-0" }) : null, t.raw('text1a2303ede074')] })] })] }));
|
|
64
66
|
}
|
|
65
67
|
function TelegramUsersField({ value, onChange, invalid, }) {
|
|
66
68
|
const t = useTranslations('hardcodedUi.i18nComplete');
|
|
67
|
-
return (_jsxs(Field, { children: [_jsx(FieldTitle, { children: t.raw('text71552d197b53') }), _jsx(Input, { inputMode:
|
|
69
|
+
return (_jsxs(Field, { children: [_jsx(FieldTitle, { children: t.raw('text71552d197b53') }), _jsx(Input, { inputMode: TELEGRAM.access.idInputMode, placeholder: TELEGRAM.access.idsPlaceholder, value: value, onChange: (event) => onChange(event.target.value), "aria-invalid": invalid }), _jsx(FieldDescription, { children: invalid ? t.raw('text50fcd9c3c020') : t.raw('text1f7a451d4722') })] }));
|
|
68
70
|
}
|
|
@@ -236,4 +236,9 @@ export const KORTIX_PERMISSIONS_CATALOG = [
|
|
|
236
236
|
actions: ['project.artifact.read', 'project.artifact.write', 'project.artifact.manage', 'project.artifact.public'],
|
|
237
237
|
featureFlag: 'artifacts',
|
|
238
238
|
},
|
|
239
|
+
{
|
|
240
|
+
group: 'Artifact comments',
|
|
241
|
+
actions: ['project.artifact.comment'],
|
|
242
|
+
featureFlag: 'artifact_comments',
|
|
243
|
+
},
|
|
239
244
|
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type ChannelPlatformId } from '../../../_vendor/shared/channel-descriptors.js';
|
|
1
2
|
/** Reserved slug for the built-in Email channel (see api connectors.ts). */
|
|
2
3
|
/** A Kortix channel's own page (`platform`), or every channel (the Channels page). */
|
|
3
|
-
export type ChannelPlatform =
|
|
4
|
+
export type ChannelPlatform = ChannelPlatformId;
|
|
4
5
|
export declare function ChannelsSection({ projectId, platform }: {
|
|
5
6
|
projectId: string;
|
|
6
7
|
platform?: ChannelPlatform;
|