@arbidocs/blocks 0.4.137 → 0.4.138

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.
Files changed (61) hide show
  1. package/dist/agents/index.cjs +380 -356
  2. package/dist/agents/index.js +8 -8
  3. package/dist/agents/skills/SkillLibraryDetail.d.ts +26 -0
  4. package/dist/agents/skills/index.d.ts +2 -0
  5. package/dist/agents/skills/skillLibrary.d.ts +46 -0
  6. package/dist/chat/index.cjs +139 -139
  7. package/dist/chat/index.js +4 -4
  8. package/dist/{chunk-CHVCTKF4.cjs → chunk-3BI6EWKP.cjs} +672 -55
  9. package/dist/chunk-3BI6EWKP.cjs.map +1 -0
  10. package/dist/{chunk-VMESMX7N.js → chunk-5BXEYYH6.js} +3 -3
  11. package/dist/{chunk-VMESMX7N.js.map → chunk-5BXEYYH6.js.map} +1 -1
  12. package/dist/{chunk-EHOPZBAX.cjs → chunk-7YLJHTDC.cjs} +11 -11
  13. package/dist/{chunk-EHOPZBAX.cjs.map → chunk-7YLJHTDC.cjs.map} +1 -1
  14. package/dist/{chunk-M33QUNFH.js → chunk-ED4HHTIA.js} +3 -3
  15. package/dist/{chunk-M33QUNFH.js.map → chunk-ED4HHTIA.js.map} +1 -1
  16. package/dist/{chunk-HDYWXEQU.cjs → chunk-IE5CUCZK.cjs} +4 -4
  17. package/dist/{chunk-HDYWXEQU.cjs.map → chunk-IE5CUCZK.cjs.map} +1 -1
  18. package/dist/{chunk-7M4C6CK7.js → chunk-JO3EMZ4X.js} +3 -3
  19. package/dist/{chunk-7M4C6CK7.js.map → chunk-JO3EMZ4X.js.map} +1 -1
  20. package/dist/{chunk-C3ZRLULA.cjs → chunk-JVL7HUIQ.cjs} +5 -5
  21. package/dist/{chunk-C3ZRLULA.cjs.map → chunk-JVL7HUIQ.cjs.map} +1 -1
  22. package/dist/{chunk-JY73DJOS.cjs → chunk-MJKBVIV3.cjs} +80 -495
  23. package/dist/{chunk-KMNZ2RVO.js.map → chunk-MJKBVIV3.cjs.map} +1 -1
  24. package/dist/{chunk-BUNZWOPX.cjs → chunk-OAL3B2ZU.cjs} +5 -5
  25. package/dist/{chunk-BUNZWOPX.cjs.map → chunk-OAL3B2ZU.cjs.map} +1 -1
  26. package/dist/{chunk-6F7SZCVL.cjs → chunk-OWCEQKAR.cjs} +3 -3
  27. package/dist/{chunk-6F7SZCVL.cjs.map → chunk-OWCEQKAR.cjs.map} +1 -1
  28. package/dist/{chunk-KMNZ2RVO.js → chunk-UBEI6WFJ.js} +10 -411
  29. package/dist/{chunk-JY73DJOS.cjs.map → chunk-UBEI6WFJ.js.map} +1 -1
  30. package/dist/{chunk-ATJUVHVB.js → chunk-XVME4XYD.js} +604 -8
  31. package/dist/chunk-XVME4XYD.js.map +1 -0
  32. package/dist/{chunk-YOMPLCP6.js → chunk-Y5KTM3V5.js} +3 -3
  33. package/dist/{chunk-YOMPLCP6.js.map → chunk-Y5KTM3V5.js.map} +1 -1
  34. package/dist/{chunk-L3T7OJRX.js → chunk-ZNI4SW2G.js} +3 -3
  35. package/dist/{chunk-L3T7OJRX.js.map → chunk-ZNI4SW2G.js.map} +1 -1
  36. package/dist/collaboration/index.cjs +9 -9
  37. package/dist/collaboration/index.js +1 -1
  38. package/dist/connect/index.cjs +436 -54
  39. package/dist/connect/index.cjs.map +1 -1
  40. package/dist/connect/index.d.ts +1 -0
  41. package/dist/connect/index.js +399 -18
  42. package/dist/connect/index.js.map +1 -1
  43. package/dist/connection/ConnectedSkillsLibrary.d.ts +26 -0
  44. package/dist/document-tools/index.cjs +1 -1
  45. package/dist/document-tools/index.js +1 -1
  46. package/dist/facts/index.cjs +2 -2
  47. package/dist/facts/index.js +2 -2
  48. package/dist/index.cjs +650 -626
  49. package/dist/index.js +15 -15
  50. package/dist/settings/index.cjs +10 -10
  51. package/dist/settings/index.js +2 -2
  52. package/dist/site/index.cjs +5 -5
  53. package/dist/site/index.js +1 -1
  54. package/dist/studio/index.cjs +6 -6
  55. package/dist/studio/index.js +5 -5
  56. package/dist/workflow-canvas/index.cjs +59 -59
  57. package/dist/workflow-canvas/index.js +8 -8
  58. package/node_modules/@arbidocs/coedit/package.json +1 -1
  59. package/package.json +4 -4
  60. package/dist/chunk-ATJUVHVB.js.map +0 -1
  61. package/dist/chunk-CHVCTKF4.cjs.map +0 -1
@@ -11,6 +11,7 @@ export { ConnectedWorkspaceNotificationMenu, ConnectedThreadFollow, type Connect
11
11
  export { ConnectedWorkspaceDataProvider, useConnectedDocuments, useConnectedTags, useConnectedConversations, type ConnectedConversation, type ConnectedWorkspaceData, type ConnectedList, type ConnectedListResult, type ConnectedDocument, type ConnectedTag, } from '../connection/workspaceData';
12
12
  export { ConnectedWorkflowsTable, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, useConnectedWorkspaceRole, type ConnectedWorkflowsTableProps, type ConnectedWorkflowsTableLabels, } from '../connection/ConnectedWorkflowsTable';
13
13
  export { ConnectedWorkflowLauncher, ConnectedWorkflowDocumentsField, useConnectedWorkflowScopeSource, useConnectedAgentOptions, toWorkflowFieldDocument, type ConnectedWorkflowLauncherProps, type ConnectedWorkflowDocumentsFieldProps, } from '../connection/ConnectedWorkflowLauncher';
14
+ export { ConnectedSkillsLibrary, type ConnectedSkillsLibraryProps, } from '../connection/ConnectedSkillsLibrary';
14
15
  export { ConnectedSkillUpload, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, type ConnectedSkillUploadProps, type ConnectedSkillUploadLabels, } from '../connection/ConnectedSkillUpload';
15
16
  export { useConnectedAiTask, useConnectedChat, ConnectedAssistantDock, useWorkspaceDocs, useSemanticSearch, toRedlineMarkdown, redlineStats, textToArtifact, type AiTaskStatus, type AiRunOptions, type SearchChunk, type ArtifactEvent, } from '../connection/ai';
16
17
  export { StreamedArtifact, type StreamedArtifactProps } from '../connection/StreamedArtifact';
@@ -1,8 +1,7 @@
1
1
  "use client";
2
- import { FilesFilterBar, FolderFilterButton, FolderPickerRow } from '../chunk-7RJTEWYM.js';
3
2
  import { SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, PasswordChangeDialog, SettingsCard, SettingsActionRow, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-OQ7RUNOC.js';
4
- import { useWorkspaceDocs } from '../chunk-L3T7OJRX.js';
5
- export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-L3T7OJRX.js';
3
+ import { useWorkspaceDocs } from '../chunk-ZNI4SW2G.js';
4
+ export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-ZNI4SW2G.js';
6
5
  import { useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-2KUCVSFF.js';
7
6
  export { ConnectedWorkspaceDataProvider, useConnectedConversations, useConnectedDocuments, useConnectedTags } from '../chunk-2KUCVSFF.js';
8
7
  import { ConnectedNativeDocxEditor } from '../chunk-E5OYHJMU.js';
@@ -12,15 +11,16 @@ import { SignDocumentDialog } from '../chunk-2YOVK524.js';
12
11
  import '../chunk-GYAUJ4KT.js';
13
12
  import '../chunk-2FL7QJKJ.js';
14
13
  import '../chunk-HFZ45FD3.js';
15
- import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-M33QUNFH.js';
14
+ import { FilesFilterBar, FolderFilterButton, FolderPickerRow } from '../chunk-7RJTEWYM.js';
15
+ import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-ED4HHTIA.js';
16
16
  import { PlainMailBodyEditor, draftMailCompose, replyMailCompose, emptyMailCompose, MailGrid, MailMessageView, MailDocumentPicker, parseMailRecipients } from '../chunk-6HCJ3ZEU.js';
17
17
  import { DOCX_MIME_TYPE } from '../chunk-QXMR5YHC.js';
18
18
  import '../chunk-AF6RDAJF.js';
19
- import { WorkflowsTable, workflowTriggerType, buildWorkflowScopeSource, documentScopeLabels, WorkflowDocumentsField, WorkflowLauncher, WorkflowStepBar, importSkillFile, importSkillFromUrl, WorkflowRunner, fromPlanSteps, toPlanSteps, useWorkflowView } from '../chunk-ATJUVHVB.js';
20
- import '../chunk-EVUEIBNU.js';
19
+ import { WorkflowsTable, workflowTriggerType, buildWorkflowScopeSource, documentScopeLabels, WorkflowDocumentsField, WorkflowLauncher, buildLibrarySkills, filterLibrarySkills, SKILL_SOURCE_LABELS, SKILL_TYPE_LABELS, SkillViewToggle, SkillFilterChips, SkillTile, SkillGenerateForm, SkillLibraryDetail, parseSkillFrontmatter, SKILL_MAIN_FILENAME, SkillEditForm, WorkflowStepBar, importSkillFile, importSkillFromUrl, WorkflowRunner, skillSlug, serializeSkill, fromPlanSteps, toPlanSteps, useWorkflowView, workflowToSkillMarkdown } from '../chunk-XVME4XYD.js';
20
+ import '../chunk-3RJN2VTL.js';
21
21
  import { TriStateFilterMenu } from '../chunk-KSHKTOY2.js';
22
22
  import '../chunk-P6GHJSLR.js';
23
- import '../chunk-3RJN2VTL.js';
23
+ import '../chunk-EVUEIBNU.js';
24
24
  import '../chunk-444XKG46.js';
25
25
  import '../chunk-NUNKSZKU.js';
26
26
  import { FilterInput } from '../chunk-YU2KUMGE.js';
@@ -29,12 +29,12 @@ import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
29
29
  import '../chunk-VILAPTCB.js';
30
30
  import { ConfirmDialog } from '../chunk-VHJHY7TT.js';
31
31
  import { TabHeader } from '../chunk-4WWM3GQ5.js';
32
- import { ChatPage } from '../chunk-7M4C6CK7.js';
32
+ import { ChatPage } from '../chunk-JO3EMZ4X.js';
33
33
  import '../chunk-7XF5SFJ2.js';
34
34
  import { takeOpenDocumentForTurn, useRegisterOpenDocument } from '../chunk-YBLIKTJK.js';
35
- import { splitDocRef, stepLevels, stepDocuments, stepKindOf, initialRunInputs, workflowSteps, stepStatesFromActivity, runThreadTitle, stepFields } from '../chunk-YOMPLCP6.js';
36
- import '../chunk-AUS3KBHJ.js';
35
+ import { splitDocRef, stepLevels, stepDocuments, stepKindOf, initialRunInputs, workflowSteps, stepStatesFromActivity, runThreadTitle, stepFields } from '../chunk-Y5KTM3V5.js';
37
36
  import '../chunk-AA3PT6KR.js';
37
+ import '../chunk-AUS3KBHJ.js';
38
38
  import '../chunk-SLSBJRWW.js';
39
39
  import '../chunk-NPLYHR2E.js';
40
40
  import '../chunk-7F6CBP3Z.js';
@@ -44,12 +44,12 @@ import { fmtDate, initials } from '../chunk-OXF2IFXG.js';
44
44
  import '../chunk-VUNV25KB.js';
45
45
  import { lazy, useState, useMemo, useEffect, useRef, useCallback, Suspense, useLayoutEffect } from 'react';
46
46
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
47
- import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useWorkflows, useAgents, useUpdateWorkflow, useDeleteWorkflow, useRunWorkflow, useArbi, useThumbnails, useUploadSkillFiles, ArtifactCanvas, useArbiChat, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useAgentSession, useStartAgentSession, useCloseAgentSession, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, useCreateWork, useActOnStep, useConversationActivity, useConversationThreads, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, AiAnswer, useMailDraftEditor } from '@arbidocs/react';
47
+ import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useWorkflows, useAgents, useUpdateWorkflow, useDeleteWorkflow, useRunWorkflow, useArbi, useThumbnails, useUploadSkillFiles, useSkills, useSetSkillVisibility, useDeleteSkill, useSkillSource, ArtifactCanvas, useArbiChat, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useSignOut, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useAgentSession, useStartAgentSession, useCloseAgentSession, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, useCreateWork, useActOnStep, useConversationActivity, useConversationThreads, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, AiAnswer, useMailDraftEditor } from '@arbidocs/react';
48
48
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
49
- import { Button, Label, Input, cn, Dialog, DialogContent, DialogTitle, DialogDescription, Tooltip, TooltipTrigger, TooltipContent } from '@arbidocs/react/ui';
50
- import { Upload, Link2, ExternalLink, UserCircle, KeyRound, Radio, Mail, Settings, Plus, ArrowLeft, Loader2, X, Paperclip, Send, MessageSquare } from 'lucide-react';
49
+ import { Button, Label, Input, cn, Textarea, Dialog, DialogContent, DialogTitle, DialogDescription, EntityIcon, Tooltip, TooltipTrigger, TooltipContent } from '@arbidocs/react/ui';
50
+ import { useIsOnline, downloadBlob, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
51
+ import { Upload, Link2, Search, Plus, ArrowLeft, ExternalLink, UserCircle, KeyRound, Radio, Mail, Settings, Loader2, X, Paperclip, Send, MessageSquare } from 'lucide-react';
51
52
  import { useStreamedArtifact } from '@arbidocs/react/artifacts';
52
- import { useIsOnline, useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
53
53
  import { useNotify } from '@arbidocs/react/shell';
54
54
  import { bytesToBase64 } from '@arbidocs/client';
55
55
  import { createPortal } from 'react-dom';
@@ -561,6 +561,387 @@ function ConnectedSkillUpload({ onDone, labels, className }) {
561
561
  }
562
562
  );
563
563
  }
564
+ var SKILL_FOLDER = "skills/";
565
+ var NAME_PATTERN = /^[a-z0-9-]{1,64}$/;
566
+ var icon = /* @__PURE__ */ jsx(EntityIcon, { entityType: "SKILL" });
567
+ var errorText = (error, fallback) => error instanceof Error && error.message ? error.message : fallback;
568
+ var statusOf = (error) => error && typeof error === "object" && "status" in error ? error.status : void 0;
569
+ function ConnectedSkillsLibrary({
570
+ builtins = [],
571
+ initialSlug,
572
+ onRun,
573
+ onDraft,
574
+ renderEditor
575
+ }) {
576
+ const arbi = useArbi();
577
+ const { confirm, notify } = useBlocksEnvironment();
578
+ const { data: listings } = useSkills();
579
+ const upload = useUploadSkillFiles();
580
+ const setVisibility = useSetSkillVisibility();
581
+ const deleteSkill = useDeleteSkill();
582
+ const [mode, setMode] = useState("detail");
583
+ const [selected, setSelected] = useState(initialSlug ?? null);
584
+ const [query, setQuery] = useState("");
585
+ const [source, setSource] = useState("all");
586
+ const [type, setType] = useState("all");
587
+ const [view, setView] = useState("gallery");
588
+ const [isBusy, setIsBusy] = useState(false);
589
+ const all = useMemo(() => buildLibrarySkills(builtins, listings ?? []), [builtins, listings]);
590
+ const shown = useMemo(
591
+ () => filterLibrarySkills(all, { query, source, type }),
592
+ [all, query, source, type]
593
+ );
594
+ const current = all.find((s) => s.slug === selected) ?? null;
595
+ const { data: currentText, isLoading: textLoading } = useSkillSource(current?.docExtId);
596
+ useEffect(() => {
597
+ if (selected && !current && all.length > 0) setSelected(null);
598
+ }, [selected, current, all.length]);
599
+ const count = (s) => all.filter((x) => x.source === s).length;
600
+ const sourceOptions = [
601
+ { id: "all", label: "All", count: all.length },
602
+ { id: "builtin", label: SKILL_SOURCE_LABELS.builtin, count: count("builtin") },
603
+ { id: "mine", label: SKILL_SOURCE_LABELS.mine, count: count("mine") },
604
+ { id: "shared", label: SKILL_SOURCE_LABELS.shared, count: count("shared") }
605
+ ];
606
+ const types = [...new Set(all.map((s) => s.type))];
607
+ const typeOptions = [
608
+ { id: "all", label: "Any kind" },
609
+ ...types.map((t) => ({ id: t, label: SKILL_TYPE_LABELS[t] ?? t }))
610
+ ];
611
+ const pick = (slug) => {
612
+ setSelected(slug);
613
+ setMode("detail");
614
+ };
615
+ const markdownOf = async (skill) => {
616
+ if (!skill.docExtId) return workflowToSkillMarkdown(skill.workflow);
617
+ const response = await arbi.documents.download(skill.docExtId);
618
+ if (!response.ok) throw new Error(`Could not read the skill (${response.status})`);
619
+ return response.text();
620
+ };
621
+ const saveAs = (slug, markdown, shared = false) => upload.mutateAsync([
622
+ {
623
+ folder: `${SKILL_FOLDER}${slug}`,
624
+ fileName: SKILL_MAIN_FILENAME,
625
+ content: new Blob([markdown], { type: "text/markdown" }),
626
+ shared
627
+ }
628
+ ]);
629
+ const busy = async (work) => {
630
+ setIsBusy(true);
631
+ try {
632
+ await work();
633
+ } finally {
634
+ setIsBusy(false);
635
+ }
636
+ };
637
+ const makeCopy = (skill) => busy(async () => {
638
+ try {
639
+ await saveAs(skill.slug, await markdownOf(skill));
640
+ notify(
641
+ "Your copy is ready. It is used instead of the original; delete it to go back.",
642
+ "success"
643
+ );
644
+ setSelected(skill.slug);
645
+ } catch (error) {
646
+ notify(errorText(error, "Could not make a copy"), "error");
647
+ }
648
+ });
649
+ const toggleShare = (skill) => {
650
+ if (!skill.docExtId) return;
651
+ const docExtId = skill.docExtId;
652
+ const next = skill.isShared ? "mine" : "global";
653
+ return busy(async () => {
654
+ try {
655
+ await setVisibility.mutateAsync({ docExtId, visibility: next });
656
+ notify(next === "global" ? "Shared with everyone" : "Made private", "success");
657
+ } catch (error) {
658
+ notify(
659
+ statusOf(error) === 409 || errorText(error, "").includes("409") ? "Someone has already shared a skill with this name. Rename yours first." : "Could not change who can see this skill",
660
+ "error"
661
+ );
662
+ }
663
+ });
664
+ };
665
+ const remove = async (skill) => {
666
+ if (!skill.docExtId) return;
667
+ const docExtId = skill.docExtId;
668
+ const ok = await confirm({
669
+ message: skill.replacesBuiltin ? `Delete your copy of "${skill.title}"? The original will be used again.` : `Delete "${skill.title}"? This cannot be undone.`,
670
+ title: "Delete skill"
671
+ });
672
+ if (!ok) return;
673
+ await busy(async () => {
674
+ try {
675
+ await deleteSkill.mutateAsync(docExtId);
676
+ notify(`${skill.title} deleted`, "success");
677
+ setSelected(null);
678
+ } catch {
679
+ notify("Could not delete the skill", "error");
680
+ }
681
+ });
682
+ };
683
+ const exportFile = async (skill) => {
684
+ try {
685
+ downloadBlob(
686
+ new Blob([await markdownOf(skill)], { type: "text/markdown" }),
687
+ SKILL_MAIN_FILENAME
688
+ );
689
+ } catch (error) {
690
+ notify(errorText(error, "Could not export the skill"), "error");
691
+ }
692
+ };
693
+ const rightVisible = mode !== "detail" || current !== null;
694
+ const backToList = () => {
695
+ setMode("detail");
696
+ setSelected(null);
697
+ };
698
+ const done = (slug) => {
699
+ if (slug) setSelected(slug);
700
+ setMode("detail");
701
+ };
702
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 border-t border-border", children: [
703
+ /* @__PURE__ */ jsxs(
704
+ "div",
705
+ {
706
+ className: cn(
707
+ "flex min-h-0 w-full flex-col md:w-[26rem] md:shrink-0 md:border-r md:border-border",
708
+ rightVisible && "max-md:hidden"
709
+ ),
710
+ "data-testid": "skills-list-pane",
711
+ children: [
712
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 p-3", children: [
713
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
714
+ /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
715
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
716
+ /* @__PURE__ */ jsx(
717
+ Input,
718
+ {
719
+ value: query,
720
+ onChange: (e) => setQuery(e.target.value),
721
+ placeholder: "Search skills",
722
+ "aria-label": "Search skills",
723
+ className: "pl-9 pointer-coarse:min-h-11",
724
+ "data-testid": "skills-browser-search"
725
+ }
726
+ )
727
+ ] }),
728
+ /* @__PURE__ */ jsx(SkillViewToggle, { value: view, onChange: setView })
729
+ ] }),
730
+ /* @__PURE__ */ jsx(
731
+ SkillFilterChips,
732
+ {
733
+ label: "Show",
734
+ value: source,
735
+ onChange: (id) => setSource(id),
736
+ options: sourceOptions
737
+ }
738
+ ),
739
+ types.length > 1 && /* @__PURE__ */ jsx(
740
+ SkillFilterChips,
741
+ {
742
+ label: "Kind",
743
+ value: type,
744
+ onChange: setType,
745
+ options: typeOptions,
746
+ testIdPrefix: "skills-type"
747
+ }
748
+ ),
749
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
750
+ /* @__PURE__ */ jsxs(
751
+ Button,
752
+ {
753
+ size: "sm",
754
+ onClick: () => setMode("new"),
755
+ className: "pointer-coarse:min-h-11",
756
+ "data-testid": "skills-new",
757
+ children: [
758
+ /* @__PURE__ */ jsx(Plus, { className: "mr-1 size-4" }),
759
+ "New skill"
760
+ ]
761
+ }
762
+ ),
763
+ /* @__PURE__ */ jsxs(
764
+ Button,
765
+ {
766
+ size: "sm",
767
+ variant: "outline",
768
+ onClick: () => setMode("add"),
769
+ className: "pointer-coarse:min-h-11",
770
+ "data-testid": "skills-add",
771
+ children: [
772
+ /* @__PURE__ */ jsx(Upload, { className: "mr-1 size-4" }),
773
+ "Add a skill"
774
+ ]
775
+ }
776
+ )
777
+ ] })
778
+ ] }),
779
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-3", "data-testid": "skills-list", children: shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-10 text-center text-sm text-muted-foreground", children: "No skills match. Try another word or filter." }) : /* @__PURE__ */ jsx(
780
+ "div",
781
+ {
782
+ className: cn(
783
+ "gap-2",
784
+ view === "gallery" ? "grid grid-cols-[repeat(auto-fill,minmax(9.5rem,1fr))]" : "flex flex-col"
785
+ ),
786
+ children: shown.map((skill) => /* @__PURE__ */ jsx(
787
+ SkillTile,
788
+ {
789
+ name: skill.title,
790
+ testId: `skill-tile-${skill.slug}`,
791
+ description: skill.description,
792
+ sourceLabel: skill.isShared ? `${SKILL_SOURCE_LABELS.mine}, shared` : SKILL_SOURCE_LABELS[skill.source],
793
+ type: skill.type,
794
+ icon,
795
+ layout: view,
796
+ selected: skill.slug === selected,
797
+ onSelect: () => pick(skill.slug)
798
+ },
799
+ skill.slug
800
+ ))
801
+ }
802
+ ) })
803
+ ]
804
+ }
805
+ ),
806
+ /* @__PURE__ */ jsxs(
807
+ "div",
808
+ {
809
+ className: cn("flex min-h-0 min-w-0 flex-1 flex-col", !rightVisible && "max-md:hidden"),
810
+ "data-testid": "skills-detail-pane",
811
+ children: [
812
+ rightVisible && /* @__PURE__ */ jsxs(
813
+ Button,
814
+ {
815
+ variant: "ghost",
816
+ size: "sm",
817
+ onClick: backToList,
818
+ className: "m-2 self-start pointer-coarse:min-h-11 md:hidden",
819
+ "data-testid": "skills-back",
820
+ children: [
821
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-1 size-4" }),
822
+ "All skills"
823
+ ]
824
+ }
825
+ ),
826
+ mode === "new" && /* @__PURE__ */ jsx(
827
+ SkillGenerateForm,
828
+ {
829
+ icon,
830
+ onGenerate: (desc) => {
831
+ onDraft(`/create-skill ${desc}`.trim() + " ");
832
+ notify("Sent to the chat: the assistant will draft your skill.", "info");
833
+ },
834
+ onManual: () => setMode("edit")
835
+ }
836
+ ),
837
+ mode === "edit" && /* @__PURE__ */ jsx(
838
+ SkillEditor,
839
+ {
840
+ skill: current?.source === "mine" ? current : null,
841
+ text: current?.source === "mine" ? currentText : void 0,
842
+ renderEditor,
843
+ onSave: async (slug, markdown, isEditing) => {
844
+ await saveAs(slug, markdown, isEditing && !!current?.isShared);
845
+ notify(isEditing ? `${slug} saved` : `${slug} added`, "success");
846
+ done(slug);
847
+ },
848
+ onCancel: () => done(),
849
+ isSaving: upload.isPending
850
+ }
851
+ ),
852
+ mode === "add" && /* @__PURE__ */ jsx(ConnectedSkillUpload, { onDone: done }),
853
+ mode === "detail" && current && /* @__PURE__ */ jsx(
854
+ SkillLibraryDetail,
855
+ {
856
+ skill: current,
857
+ icon,
858
+ instructions: current.docExtId ? currentText ? parseSkillFrontmatter(currentText, SKILL_MAIN_FILENAME).content : "" : current.workflow.run.kind === "prompt" ? current.workflow.run.promptTemplate : "",
859
+ isLoading: !!current.docExtId && textLoading,
860
+ actions: {
861
+ onRun: () => onRun(current.slug),
862
+ onCopy: () => void makeCopy(current),
863
+ onEdit: () => setMode("edit"),
864
+ onToggleShare: () => void toggleShare(current),
865
+ onExport: () => void exportFile(current),
866
+ onDelete: () => void remove(current),
867
+ isBusy
868
+ }
869
+ }
870
+ ),
871
+ mode === "detail" && !current && /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center p-8 text-center text-sm text-muted-foreground max-md:hidden", children: "Pick a skill to read it, run it or make a copy." })
872
+ ]
873
+ }
874
+ )
875
+ ] });
876
+ }
877
+ function SkillEditor({
878
+ skill,
879
+ text,
880
+ renderEditor,
881
+ onSave,
882
+ onCancel,
883
+ isSaving
884
+ }) {
885
+ const { notify } = useBlocksEnvironment();
886
+ const isEditing = !!skill;
887
+ const [name, setName] = useState(skill?.slug ?? "");
888
+ const [description, setDescription] = useState("");
889
+ const [body, setBody] = useState("");
890
+ const [seeded, setSeeded] = useState(!isEditing);
891
+ const [nameError, setNameError] = useState(null);
892
+ if (isEditing && !seeded && text !== void 0) {
893
+ const parsed = parseSkillFrontmatter(text, SKILL_MAIN_FILENAME);
894
+ setDescription(parsed.description ?? "");
895
+ setBody(parsed.content ?? "");
896
+ setSeeded(true);
897
+ }
898
+ const save = async () => {
899
+ if (!NAME_PATTERN.test(name)) {
900
+ setNameError("Use 1\u201364 lowercase letters, numbers or hyphens.");
901
+ return;
902
+ }
903
+ if (description.trim().length < 1) {
904
+ notify("Add a short description.", "error");
905
+ return;
906
+ }
907
+ const slug = skillSlug(name);
908
+ try {
909
+ await onSave(slug, serializeSkill({ name: slug, description, body }), isEditing);
910
+ } catch (err) {
911
+ notify(errorText(err, "Could not save the skill"), "error");
912
+ }
913
+ };
914
+ return /* @__PURE__ */ jsx(
915
+ SkillEditForm,
916
+ {
917
+ name,
918
+ onNameChange: setName,
919
+ isNameLocked: isEditing,
920
+ nameError,
921
+ description,
922
+ onDescriptionChange: setDescription,
923
+ editor: renderEditor ? renderEditor(body, setBody) : /* @__PURE__ */ jsx(
924
+ Textarea,
925
+ {
926
+ value: body,
927
+ onChange: (e) => setBody(e.target.value),
928
+ className: "min-h-64 flex-1 font-mono text-sm",
929
+ "aria-label": "Instructions"
930
+ }
931
+ ),
932
+ isSaving,
933
+ isEditing,
934
+ onSave: save,
935
+ onCancel,
936
+ labels: { create: "Add skill" },
937
+ testIds: {
938
+ name: "skill-edit-name",
939
+ description: "skill-edit-description",
940
+ save: "skill-edit-save"
941
+ }
942
+ }
943
+ );
944
+ }
564
945
  var StreamedArtifactEditor = lazy(() => import('../StreamedArtifactEditor-XQNANTWM.js'));
565
946
  function StreamedArtifact({
566
947
  artifacts,
@@ -1650,7 +2031,7 @@ function useConnectedShellWorkspaces(options = {}) {
1650
2031
  select: (workspace) => setWorkspace(workspace.id)
1651
2032
  });
1652
2033
  }
1653
- function errorText(error, fallback) {
2034
+ function errorText2(error, fallback) {
1654
2035
  const body = error?.apiError;
1655
2036
  return typeof body?.detail === "string" ? body.detail : fallback;
1656
2037
  }
@@ -1700,7 +2081,7 @@ function ConnectedProfileCard({
1700
2081
  await requestEmailChange.mutateAsync(address);
1701
2082
  notify("Verification code sent to your new email", "success");
1702
2083
  } catch (e) {
1703
- notify(errorText(e, "Failed to send verification code"), "error");
2084
+ notify(errorText2(e, "Failed to send verification code"), "error");
1704
2085
  throw e;
1705
2086
  }
1706
2087
  },
@@ -1709,7 +2090,7 @@ function ConnectedProfileCard({
1709
2090
  await confirmEmailChange.mutateAsync(args);
1710
2091
  notify("Email address updated", "success");
1711
2092
  } catch (e) {
1712
- notify(errorText(e, "Invalid or expired verification code"), "error");
2093
+ notify(errorText2(e, "Invalid or expired verification code"), "error");
1713
2094
  throw e;
1714
2095
  }
1715
2096
  }
@@ -4163,6 +4544,6 @@ function ConnectedAgentChatPanel({
4163
4544
  ] });
4164
4545
  }
4165
4546
 
4166
- export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowRunner, ConnectedWorkflowsTable, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultUnmetPasswordRequirement, resolveMailbox, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole };
4547
+ export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedPasswordChangeDialog, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedSkillsLibrary, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowDocumentsField, ConnectedWorkflowLauncher, ConnectedWorkflowRunner, ConnectedWorkflowsTable, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_SKILL_UPLOAD_LABELS, DEFAULT_CONNECTED_WORKFLOWS_TABLE_LABELS, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultUnmetPasswordRequirement, resolveMailbox, toWorkflowFieldDocument, useConnectedAgentOptions, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications, useConnectedWorkflowScopeSource, useConnectedWorkspaceRole };
4167
4548
  //# sourceMappingURL=index.js.map
4168
4549
  //# sourceMappingURL=index.js.map