@epam/ai-dial-skill-editor 1.0.0-rc.5
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/components/SkillEditor/SkillEditor.d.ts +5 -0
- package/components/SkillEditor/SkillEditor.d.ts.map +1 -0
- package/components/SkillFileDropOverlay/SkillFileDropOverlay.d.ts +16 -0
- package/components/SkillFileDropOverlay/SkillFileDropOverlay.d.ts.map +1 -0
- package/components/SkillFileUploadDialog/SkillFileUploadDialog.d.ts +24 -0
- package/components/SkillFileUploadDialog/SkillFileUploadDialog.d.ts.map +1 -0
- package/hooks/useSkillFileDropZone.d.ts +27 -0
- package/hooks/useSkillFileDropZone.d.ts.map +1 -0
- package/index.css +2 -0
- package/index.d.ts +5 -0
- package/index.d.ts.map +1 -0
- package/index.js +537 -0
- package/models/skill-editor-props.d.ts +298 -0
- package/models/skill-editor-props.d.ts.map +1 -0
- package/package.json +30 -0
- package/test-setup.d.ts +1 -0
- package/test-setup.d.ts.map +1 -0
- package/types/skill-editor-defaults.d.ts +3 -0
- package/types/skill-editor-defaults.d.ts.map +1 -0
- package/types/skill-file-node-kind.d.ts +8 -0
- package/types/skill-file-node-kind.d.ts.map +1 -0
- package/utils/candidate-path.d.ts +7 -0
- package/utils/candidate-path.d.ts.map +1 -0
- package/utils/file-tree.d.ts +10 -0
- package/utils/file-tree.d.ts.map +1 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { SkillEditorProps } from '../../models/skill-editor-props';
|
|
3
|
+
/** Host-agnostic form for authoring a DIAL Skill's manifest and supporting files. */
|
|
4
|
+
export declare const SkillEditor: FC<SkillEditorProps>;
|
|
5
|
+
//# sourceMappingURL=SkillEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillEditor.d.ts","sourceRoot":"","sources":["../../../src/components/SkillEditor/SkillEditor.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAEL,EAAE,EASH,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,gBAAgB,EAGjB,MAAM,iCAAiC,CAAC;AAqBzC,qFAAqF;AACrF,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAmc5C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { SkillEditorLabels } from '../../models/skill-editor-props';
|
|
3
|
+
/** Props for `SkillFileDropOverlay`. */
|
|
4
|
+
export interface SkillFileDropOverlayProps {
|
|
5
|
+
/** Whether the overlay is shown. */
|
|
6
|
+
isVisible: boolean;
|
|
7
|
+
/** Text overrides. */
|
|
8
|
+
labels?: Pick<SkillEditorLabels, 'dropOverlayTitle' | 'dropOverlaySubtitle'>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Full-surface overlay shown while a file-bearing drag is over the editor
|
|
12
|
+
* and the upload dialog isn't open yet, mirroring the chat composer's
|
|
13
|
+
* page-wide drag overlay so the interaction feels consistent app-wide.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SkillFileDropOverlay: FC<SkillFileDropOverlayProps>;
|
|
16
|
+
//# sourceMappingURL=SkillFileDropOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillFileDropOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/SkillFileDropOverlay/SkillFileDropOverlay.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,wCAAwC;AACxC,MAAM,WAAW,yBAAyB;IACxC,oCAAoC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,sBAAsB;IACtB,MAAM,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,kBAAkB,GAAG,qBAAqB,CAAC,CAAC;CAC9E;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CA0B9D,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { SkillEditorFileActions, SkillEditorLabels } from '../../models/skill-editor-props';
|
|
3
|
+
/** Props for `SkillFileUploadDialog`. */
|
|
4
|
+
export interface SkillFileUploadDialogProps {
|
|
5
|
+
/** Whether the dialog is open. */
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
/** Called to close the dialog (Escape, close control, Cancel, or a successful commit). */
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
/** Batch validation/commit operations, host-owned. */
|
|
10
|
+
fileActions: Pick<SkillEditorFileActions, 'validateBatch' | 'commitBatch'>;
|
|
11
|
+
/**
|
|
12
|
+
* Files to stage immediately when the dialog opens (e.g. files dropped
|
|
13
|
+
* outside the dialog before it was open). Read once per open transition.
|
|
14
|
+
*/
|
|
15
|
+
initialFiles?: File[];
|
|
16
|
+
/** Text overrides. */
|
|
17
|
+
labels?: SkillEditorLabels;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Upload dialog offering drag-and-drop and click-to-browse multi-file
|
|
21
|
+
* staging, with per-row validation feedback and an atomic batch commit.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SkillFileUploadDialog: FC<SkillFileUploadDialogProps>;
|
|
24
|
+
//# sourceMappingURL=SkillFileUploadDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillFileUploadDialog.d.ts","sourceRoot":"","sources":["../../../src/components/SkillFileUploadDialog/SkillFileUploadDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAe,EAAE,EAAE,MAAM,OAAO,CAAC;AAG7C,OAAO,KAAK,EACV,sBAAsB,EACtB,iBAAiB,EAGlB,MAAM,iCAAiC,CAAC;AAOzC,yCAAyC;AACzC,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,sDAAsD;IACtD,WAAW,EAAE,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC;IAC3E;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC;IACtB,sBAAsB;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAWD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CAoQhE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DragEvent } from 'react';
|
|
2
|
+
/** React drag-event handlers to spread onto a drop-zone element. */
|
|
3
|
+
export interface SkillFileDropZoneHandlers {
|
|
4
|
+
/** Attach to the drop-zone element's `onDragEnter`. */
|
|
5
|
+
onDragEnter: (event: DragEvent<HTMLElement>) => void;
|
|
6
|
+
/** Attach to the drop-zone element's `onDragLeave`. */
|
|
7
|
+
onDragLeave: (event: DragEvent<HTMLElement>) => void;
|
|
8
|
+
/** Attach to the drop-zone element's `onDragOver`. */
|
|
9
|
+
onDragOver: (event: DragEvent<HTMLElement>) => void;
|
|
10
|
+
/** Attach to the drop-zone element's `onDrop`. */
|
|
11
|
+
onDrop: (event: DragEvent<HTMLElement>) => void;
|
|
12
|
+
}
|
|
13
|
+
/** State and handlers returned by `useSkillFileDropZone`. */
|
|
14
|
+
export interface SkillFileDropZoneState {
|
|
15
|
+
/** Whether a file-bearing drag is currently over the drop zone. */
|
|
16
|
+
isDragActive: boolean;
|
|
17
|
+
/** Handlers to spread onto the drop-zone element. */
|
|
18
|
+
dropZoneHandlers: SkillFileDropZoneHandlers;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Scoped drag-and-drop state for a single drop-zone element, using the same
|
|
22
|
+
* nested-enter/leave counting technique as the app's page-wide
|
|
23
|
+
* `usePageFileDrag`, but attached directly to the element's own React drag
|
|
24
|
+
* events instead of `document` listeners.
|
|
25
|
+
*/
|
|
26
|
+
export declare const useSkillFileDropZone: (onFilesDropped: (files: File[]) => void) => SkillFileDropZoneState;
|
|
27
|
+
//# sourceMappingURL=useSkillFileDropZone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSkillFileDropZone.d.ts","sourceRoot":"","sources":["../../src/hooks/useSkillFileDropZone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,oEAAoE;AACpE,MAAM,WAAW,yBAAyB;IACxC,uDAAuD;IACvD,WAAW,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACrD,uDAAuD;IACvD,WAAW,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACrD,sDAAsD;IACtD,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACpD,kDAAkD;IAClD,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CACjD;AAED,6DAA6D;AAC7D,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,gBAAgB,EAAE,yBAAyB,CAAC;CAC7C;AAKD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,KACtC,sBAyCF,CAAC"}
|
package/index.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
._title_l82ak_1{color:var(--se-title-color,var(--text-primary,#161b2d))}._helperText_l82ak_5{color:var(--se-helper-text-color,var(--text-secondary,#57647a))}._headerBorder_l82ak_9{border-bottom-color:var(--se-border-color,var(--stroke-tertiary,#e0e6f0))}._sidebarBorder_l82ak_13{border-inline-end-color:var(--se-border-color,var(--stroke-tertiary,#e0e6f0))}._actionBarBorder_l82ak_17{border-top-color:var(--se-border-color,var(--stroke-tertiary,#e0e6f0))}
|
|
2
|
+
/*$vite$:1*/
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SkillEditor } from './components/SkillEditor/SkillEditor';
|
|
2
|
+
export type { SkillEditorColors, SkillEditorConflict, SkillEditorErrors, SkillEditorFileActions, SkillEditorLabels, SkillEditorProps, SkillEditorStyles, SkillEditorTypography, SkillEditorValues, SkillFileBatchError, SkillFileCommitResult, SkillFileTreeNode, SkillFileUploadCandidate, SkillFileValidationResult, } from './models/skill-editor-props';
|
|
3
|
+
export { SkillFileCandidateKind, SkillFileValidationStatus, } from './models/skill-editor-props';
|
|
4
|
+
export { SkillFileNodeKind } from './types/skill-file-node-kind';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import { buildCssVars as e, formatFileSize as t, mergeClasses as n } from "@epam/ai-dial-chat-shared";
|
|
2
|
+
import { DialFileNodeType as r, DialFoldersTree as i } from "@epam/ai-dial-react-file-manager";
|
|
3
|
+
import { Accordion as a, CaptionText as ee, DIAL_ICON_SIZE as o, EditorThemes as s, ErrorText as c, GhostButton as l, GhostIconButton as te, Input as u, LazyMarkdownEditor as d, NeutralButton as f, Popup as ne, PopupSize as p, PrimaryButton as m, Spinner as h, Textarea as g } from "@epam/ai-dial-ui-kit";
|
|
4
|
+
import { IconFileText as re, IconPlus as _, IconTrashX as ie, IconUpload as v } from "@tabler/icons-react";
|
|
5
|
+
import { Suspense as y, lazy as b, useCallback as x, useEffect as S, useId as C, useMemo as w, useRef as T, useState as E } from "react";
|
|
6
|
+
import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
|
|
7
|
+
//#region src/hooks/useSkillFileDropZone.ts
|
|
8
|
+
var A = (e) => !!e.dataTransfer?.types.includes("Files"), ae = (e) => {
|
|
9
|
+
let [t, n] = E(!1), r = T(0);
|
|
10
|
+
return {
|
|
11
|
+
isDragActive: t,
|
|
12
|
+
dropZoneHandlers: {
|
|
13
|
+
onDragEnter: x((e) => {
|
|
14
|
+
A(e) && (e.preventDefault(), r.current += 1, n(!0));
|
|
15
|
+
}, []),
|
|
16
|
+
onDragLeave: x((e) => {
|
|
17
|
+
A(e) && (--r.current, r.current <= 0 && (r.current = 0, n(!1)));
|
|
18
|
+
}, []),
|
|
19
|
+
onDragOver: x((e) => {
|
|
20
|
+
A(e) && e.preventDefault();
|
|
21
|
+
}, []),
|
|
22
|
+
onDrop: x((t) => {
|
|
23
|
+
if (!A(t)) return;
|
|
24
|
+
t.preventDefault(), r.current = 0, n(!1);
|
|
25
|
+
let i = Array.from(t.dataTransfer?.files ?? []);
|
|
26
|
+
i.length > 0 && e(i);
|
|
27
|
+
}, [e])
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}, j = "SKILL.md", M = /* @__PURE__ */ function(e) {
|
|
31
|
+
return e.File = "file", e.Folder = "folder", e;
|
|
32
|
+
}({}), N = (e) => {
|
|
33
|
+
let t = e.lastIndexOf("/");
|
|
34
|
+
return t === -1 ? null : e.slice(0, t);
|
|
35
|
+
}, P = (e) => {
|
|
36
|
+
let t = e.lastIndexOf("/");
|
|
37
|
+
return t === -1 ? e : e.slice(t + 1);
|
|
38
|
+
}, oe = (e) => {
|
|
39
|
+
let t = /* @__PURE__ */ new Map(), n = (e) => {
|
|
40
|
+
let n = t.get(e);
|
|
41
|
+
if (n) return n;
|
|
42
|
+
let i = {
|
|
43
|
+
path: e,
|
|
44
|
+
name: P(e),
|
|
45
|
+
nodeType: r.FOLDER,
|
|
46
|
+
parentPath: N(e),
|
|
47
|
+
folderId: e,
|
|
48
|
+
items: []
|
|
49
|
+
};
|
|
50
|
+
return t.set(e, i), i;
|
|
51
|
+
};
|
|
52
|
+
for (let i of e) {
|
|
53
|
+
if (i.kind === M.Folder) {
|
|
54
|
+
n(i.path);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
t.set(i.path, {
|
|
58
|
+
path: i.path,
|
|
59
|
+
name: i.name,
|
|
60
|
+
nodeType: r.ITEM,
|
|
61
|
+
parentPath: N(i.path),
|
|
62
|
+
folderId: N(i.path) ?? ""
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
for (let t of [...e]) {
|
|
66
|
+
let e = N(t.path);
|
|
67
|
+
for (; e != null;) n(e), e = N(e);
|
|
68
|
+
}
|
|
69
|
+
let i = [];
|
|
70
|
+
for (let e of t.values()) {
|
|
71
|
+
if (e.parentPath == null) {
|
|
72
|
+
i.push(e);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
let n = t.get(e.parentPath);
|
|
76
|
+
n ? n.items = [...n.items ?? [], e] : i.push(e);
|
|
77
|
+
}
|
|
78
|
+
return i;
|
|
79
|
+
}, se = ({ isVisible: e, labels: t }) => {
|
|
80
|
+
if (!e) return null;
|
|
81
|
+
let r = t ?? {};
|
|
82
|
+
return /* @__PURE__ */ O("div", {
|
|
83
|
+
role: "status",
|
|
84
|
+
"aria-live": "polite",
|
|
85
|
+
className: n("pointer-events-none absolute inset-0 z-[100] flex items-center justify-center backdrop-blur-sm"),
|
|
86
|
+
children: /* @__PURE__ */ k("div", {
|
|
87
|
+
className: "flex flex-col items-center text-center",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ O(v, {
|
|
90
|
+
size: 100,
|
|
91
|
+
className: "text-accent-primary",
|
|
92
|
+
"aria-hidden": !0
|
|
93
|
+
}),
|
|
94
|
+
/* @__PURE__ */ O("span", {
|
|
95
|
+
className: "dial-h3-text mt-5",
|
|
96
|
+
children: r.dropOverlayTitle ?? "Upload files"
|
|
97
|
+
}),
|
|
98
|
+
/* @__PURE__ */ O("span", {
|
|
99
|
+
className: "dial-small-text mt-4",
|
|
100
|
+
children: r.dropOverlaySubtitle ?? "Drop files here to add them to this skill"
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}, F = /* @__PURE__ */ function(e) {
|
|
106
|
+
return e.SupportingFile = "supporting-file", e.Manifest = "manifest", e;
|
|
107
|
+
}({}), I = /* @__PURE__ */ function(e) {
|
|
108
|
+
return e.Valid = "valid", e.Invalid = "invalid", e;
|
|
109
|
+
}({}), L = (e) => (e.webkitRelativePath || e.name).replace(/\\/g, "/"), R = 0, z = () => `skill-file-candidate-${++R}`, ce = ({ isOpen: e, onClose: r, fileActions: i, initialFiles: a, labels: ee }) => {
|
|
110
|
+
let o = ee ?? {}, s = T(null), [u, d] = E([]), [f, g] = E(/* @__PURE__ */ new Map()), [_, y] = E([]), [b, x] = E(!1), [w, D] = E(), [A, j] = E(!1), M = C(), N = (e) => {
|
|
111
|
+
let t = e.map((e) => ({
|
|
112
|
+
id: z(),
|
|
113
|
+
file: e,
|
|
114
|
+
path: L(e)
|
|
115
|
+
}));
|
|
116
|
+
D(void 0), d((e) => [...e, ...t]);
|
|
117
|
+
}, P = (e) => {
|
|
118
|
+
d((t) => t.filter((t) => t.id !== e));
|
|
119
|
+
}, { isDragActive: oe, dropZoneHandlers: se } = ae(N);
|
|
120
|
+
S(() => {
|
|
121
|
+
e && (d((a ?? []).map((e) => ({
|
|
122
|
+
id: z(),
|
|
123
|
+
file: e,
|
|
124
|
+
path: L(e)
|
|
125
|
+
}))), g(/* @__PURE__ */ new Map()), y([]), D(void 0));
|
|
126
|
+
}, [e]), S(() => {
|
|
127
|
+
if (!e) return;
|
|
128
|
+
let t = !1;
|
|
129
|
+
if (u.length === 0) {
|
|
130
|
+
g(/* @__PURE__ */ new Map()), y([]);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
return x(!0), i.validateBatch(u).then(({ results: e, batchErrors: n }) => {
|
|
134
|
+
t || (g(new Map(e.map((e) => [e.candidateId, e]))), y(n.map((e) => e.message)));
|
|
135
|
+
}).finally(() => {
|
|
136
|
+
t || x(!1);
|
|
137
|
+
}), () => {
|
|
138
|
+
t = !0;
|
|
139
|
+
};
|
|
140
|
+
}, [u, e]);
|
|
141
|
+
let R = (e) => {
|
|
142
|
+
let t = Array.from(e.target.files ?? []);
|
|
143
|
+
e.target.value = "", t.length > 0 && N(t);
|
|
144
|
+
}, ce = u.some((e) => f.get(e.id)?.status === I.Invalid), B = u.length > 0 && u.every((e) => f.get(e.id)?.status === I.Invalid), le = u.length > 0 && !ce && _.length === 0 && !b && !A, V = async () => {
|
|
145
|
+
j(!0), D(void 0);
|
|
146
|
+
try {
|
|
147
|
+
let { results: e, batchErrors: t } = await i.validateBatch(u), n = new Map(e.map((e) => [e.candidateId, e]));
|
|
148
|
+
if (g(n), y(t.map((e) => e.message)), u.some((e) => n.get(e.id)?.status === I.Invalid) || t.length > 0) return;
|
|
149
|
+
let a = await i.commitBatch(u);
|
|
150
|
+
if (a.error) {
|
|
151
|
+
D(a.error);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
r();
|
|
155
|
+
} finally {
|
|
156
|
+
j(!1);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
return /* @__PURE__ */ O(ne, {
|
|
160
|
+
open: e,
|
|
161
|
+
header: o.uploadDialogTitle ?? "Upload files from device",
|
|
162
|
+
size: p.Sm,
|
|
163
|
+
closeAriaLabel: o.uploadDialogCloseAriaLabel ?? "Close",
|
|
164
|
+
onClose: r,
|
|
165
|
+
footer: /* @__PURE__ */ k("div", {
|
|
166
|
+
className: "flex min-h-[44px] items-center justify-end gap-2 px-6 py-4",
|
|
167
|
+
children: [/* @__PURE__ */ O(l, {
|
|
168
|
+
label: o.uploadCancelLabel ?? "Cancel",
|
|
169
|
+
onClick: r
|
|
170
|
+
}), /* @__PURE__ */ O(m, {
|
|
171
|
+
label: o.uploadConfirmLabel ?? "Add",
|
|
172
|
+
iconBefore: A ? /* @__PURE__ */ O(h, {
|
|
173
|
+
size: 16,
|
|
174
|
+
ariaLabel: ""
|
|
175
|
+
}) : void 0,
|
|
176
|
+
onClick: () => void V(),
|
|
177
|
+
disabled: !le
|
|
178
|
+
})]
|
|
179
|
+
}),
|
|
180
|
+
children: /* @__PURE__ */ k("div", {
|
|
181
|
+
className: "flex flex-col gap-4 px-6 py-4",
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ k("div", {
|
|
184
|
+
role: "button",
|
|
185
|
+
tabIndex: 0,
|
|
186
|
+
"aria-label": o.uploadDropZoneAriaLabel ?? "Upload files",
|
|
187
|
+
className: n("bg-layer-2 flex min-h-[164px] cursor-pointer flex-col items-center justify-center gap-4 rounded-lg border border-dashed border-secondary px-6 py-9 focus-visible:outline focus-visible:outline-focus-black", oe && "bg-layer-3 border-accent-primary", B && "border-error"),
|
|
188
|
+
onClick: () => s.current?.click(),
|
|
189
|
+
onKeyDown: (e) => {
|
|
190
|
+
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), s.current?.click());
|
|
191
|
+
},
|
|
192
|
+
...se,
|
|
193
|
+
children: [/* @__PURE__ */ O(v, {
|
|
194
|
+
size: 32,
|
|
195
|
+
"aria-hidden": !0
|
|
196
|
+
}), /* @__PURE__ */ k("div", {
|
|
197
|
+
className: "flex flex-col items-center gap-2 text-center",
|
|
198
|
+
children: [/* @__PURE__ */ O("span", {
|
|
199
|
+
className: "dial-small-text desktop:hidden",
|
|
200
|
+
children: o.uploadDropZoneMobileLabel ?? "Click here to upload"
|
|
201
|
+
}), /* @__PURE__ */ O("span", {
|
|
202
|
+
className: "dial-small-text hidden desktop:inline",
|
|
203
|
+
children: o.uploadDropZoneLabel ?? "Drag and drop it or click here to upload"
|
|
204
|
+
})]
|
|
205
|
+
})]
|
|
206
|
+
}),
|
|
207
|
+
/* @__PURE__ */ O("input", {
|
|
208
|
+
ref: s,
|
|
209
|
+
type: "file",
|
|
210
|
+
multiple: !0,
|
|
211
|
+
className: "hidden",
|
|
212
|
+
onChange: R
|
|
213
|
+
}),
|
|
214
|
+
/* @__PURE__ */ O("span", {
|
|
215
|
+
role: "status",
|
|
216
|
+
"aria-live": "polite",
|
|
217
|
+
className: "sr-only",
|
|
218
|
+
id: M,
|
|
219
|
+
children: _.map((e) => `${o.uploadBatchErrorAriaPrefix ?? "Upload error: "}${e}`).join(" ")
|
|
220
|
+
}),
|
|
221
|
+
_.map((e) => /* @__PURE__ */ O(c, { text: e }, e)),
|
|
222
|
+
u.length > 0 && /* @__PURE__ */ O("ul", {
|
|
223
|
+
className: "flex flex-col gap-2",
|
|
224
|
+
children: u.map((e) => {
|
|
225
|
+
let n = f.get(e.id), r = n?.kind === F.Manifest, i = n?.status === I.Invalid;
|
|
226
|
+
return /* @__PURE__ */ k("li", {
|
|
227
|
+
className: "flex items-center gap-2 rounded-lg border border-tertiary p-2",
|
|
228
|
+
children: [
|
|
229
|
+
/* @__PURE__ */ O(re, {
|
|
230
|
+
size: 20,
|
|
231
|
+
"aria-hidden": !0
|
|
232
|
+
}),
|
|
233
|
+
/* @__PURE__ */ k("div", {
|
|
234
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
235
|
+
children: [
|
|
236
|
+
/* @__PURE__ */ O("span", {
|
|
237
|
+
className: "dial-small-text truncate",
|
|
238
|
+
children: e.path
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ O("span", {
|
|
241
|
+
className: "dial-tiny-text text-secondary",
|
|
242
|
+
children: t(e.file.size)
|
|
243
|
+
}),
|
|
244
|
+
i && n?.error && /* @__PURE__ */ O(c, { text: n.error }),
|
|
245
|
+
r && !i && /* @__PURE__ */ O("span", {
|
|
246
|
+
className: "dial-tiny-text text-secondary",
|
|
247
|
+
children: o.uploadManifestRowNote ?? "Will replace this Skill's name, description, and instructions"
|
|
248
|
+
})
|
|
249
|
+
]
|
|
250
|
+
}),
|
|
251
|
+
/* @__PURE__ */ O(te, {
|
|
252
|
+
icon: /* @__PURE__ */ O(ie, {
|
|
253
|
+
size: 16,
|
|
254
|
+
"aria-hidden": !0
|
|
255
|
+
}),
|
|
256
|
+
"aria-label": o.uploadRemoveCandidateLabel?.(e.path) ?? `Remove ${e.path}`,
|
|
257
|
+
onClick: () => P(e.id)
|
|
258
|
+
})
|
|
259
|
+
]
|
|
260
|
+
}, e.id);
|
|
261
|
+
})
|
|
262
|
+
}),
|
|
263
|
+
w && /* @__PURE__ */ O(c, { text: w })
|
|
264
|
+
]
|
|
265
|
+
})
|
|
266
|
+
});
|
|
267
|
+
}, B = {
|
|
268
|
+
title: "_title_l82ak_1",
|
|
269
|
+
helperText: "_helperText_l82ak_5",
|
|
270
|
+
headerBorder: "_headerBorder_l82ak_9",
|
|
271
|
+
sidebarBorder: "_sidebarBorder_l82ak_13",
|
|
272
|
+
actionBarBorder: "_actionBarBorder_l82ak_17"
|
|
273
|
+
}, le = b(async () => {
|
|
274
|
+
let { MarkdownEditor: e } = await d();
|
|
275
|
+
return { default: e };
|
|
276
|
+
}), V = ({ initialValues: t, files: r, selectedPath: te, onSelectedPathChange: d, expandedPaths: ne, onExpandedPathsChange: p, isLoading: re = !1, hasLoadError: v = !1, isSubmitting: b = !1, errors: A, submitError: N, conflict: P, onReloadLatest: F, isNameReadOnly: I = !1, onDirtyChange: L, fileActions: R, headerContent: z, supportingFileContent: V, onSubmit: ue, onCancel: de, onRetry: fe, labels: H, styles: pe, dir: me, instructionsEditorTheme: he = s.light }) => {
|
|
277
|
+
let [U, W] = E({
|
|
278
|
+
name: t?.name ?? "",
|
|
279
|
+
description: t?.description ?? "",
|
|
280
|
+
instructions: t?.instructions ?? ""
|
|
281
|
+
}), ge = T(r);
|
|
282
|
+
S(() => {
|
|
283
|
+
W({
|
|
284
|
+
name: t?.name ?? "",
|
|
285
|
+
description: t?.description ?? "",
|
|
286
|
+
instructions: t?.instructions ?? ""
|
|
287
|
+
}), ge.current = r;
|
|
288
|
+
}, [t]);
|
|
289
|
+
let _e = (e) => JSON.stringify([...e].sort((e, t) => e.path.localeCompare(t.path))), ve = T(!1);
|
|
290
|
+
S(() => {
|
|
291
|
+
let e = {
|
|
292
|
+
name: t?.name ?? "",
|
|
293
|
+
description: t?.description ?? "",
|
|
294
|
+
instructions: t?.instructions ?? ""
|
|
295
|
+
}, n = JSON.stringify(U) !== JSON.stringify(e) || _e(r) !== _e(ge.current);
|
|
296
|
+
n !== ve.current && (ve.current = n, L?.(n));
|
|
297
|
+
}, [
|
|
298
|
+
U,
|
|
299
|
+
r,
|
|
300
|
+
t,
|
|
301
|
+
L
|
|
302
|
+
]);
|
|
303
|
+
let [ye, be] = E(j), G = te ?? ye, K = x((e) => {
|
|
304
|
+
be(e), d?.(e);
|
|
305
|
+
}, [d]), [xe, Se] = E([]), Ce = ne ?? xe, we = w(() => new Set(Ce), [Ce]), Te = x((e) => {
|
|
306
|
+
let t = [...e];
|
|
307
|
+
Se(t), p?.(t);
|
|
308
|
+
}, [p]), [q, J] = E(!1), [Ee, Y] = E(), [De, Oe] = E(!0), { isDragActive: ke, dropZoneHandlers: Ae } = ae(x((e) => {
|
|
309
|
+
q || (Y(e), J(!0));
|
|
310
|
+
}, [q])), X = H ?? {}, Z = pe?.colors, Q = pe?.typography ?? {}, je = Q.titleClassName ?? "dial-body-semi-text", Me = Q.helperTextClassName ?? "dial-tiny-semi-text", Ne = Q.removeIconClassName ?? "text-secondary", Pe = e({
|
|
311
|
+
"--se-title-color": Z?.title,
|
|
312
|
+
"--se-helper-text-color": Z?.helperText,
|
|
313
|
+
"--se-border-color": Z?.border
|
|
314
|
+
}), Fe = w(() => oe([{
|
|
315
|
+
path: j,
|
|
316
|
+
name: j,
|
|
317
|
+
kind: M.File
|
|
318
|
+
}, ...r]), [r]), $ = w(() => r.find((e) => e.path === G), [r, G]), Ie = x((e) => {
|
|
319
|
+
K(e.path);
|
|
320
|
+
}, [K]), Le = x((e) => {
|
|
321
|
+
R.onRemoveNode(e), G === e && K(j);
|
|
322
|
+
}, [
|
|
323
|
+
R,
|
|
324
|
+
G,
|
|
325
|
+
K
|
|
326
|
+
]), Re = x((e) => e.path === "SKILL.md" ? [] : [{
|
|
327
|
+
key: "remove",
|
|
328
|
+
label: X.removeLabel ?? "Remove",
|
|
329
|
+
icon: /* @__PURE__ */ O(ie, {
|
|
330
|
+
size: o.SM,
|
|
331
|
+
className: Ne,
|
|
332
|
+
"aria-hidden": !0
|
|
333
|
+
}),
|
|
334
|
+
onClick: () => Le(e.path)
|
|
335
|
+
}], [
|
|
336
|
+
X.removeLabel,
|
|
337
|
+
Ne,
|
|
338
|
+
Le
|
|
339
|
+
]), ze = C(), Be = C(), Ve = /* @__PURE__ */ k("div", {
|
|
340
|
+
className: "flex flex-col gap-2 desktop:gap-5",
|
|
341
|
+
children: [/* @__PURE__ */ k("div", {
|
|
342
|
+
className: "flex items-center justify-between",
|
|
343
|
+
children: [/* @__PURE__ */ O("span", {
|
|
344
|
+
className: n(B.title, je),
|
|
345
|
+
children: X.filesHeading ?? "Files"
|
|
346
|
+
}), /* @__PURE__ */ O(f, {
|
|
347
|
+
label: X.addUploadLabel ?? "Upload from device",
|
|
348
|
+
iconBefore: /* @__PURE__ */ O(_, {
|
|
349
|
+
size: 16,
|
|
350
|
+
"aria-hidden": !0
|
|
351
|
+
}),
|
|
352
|
+
onClick: () => {
|
|
353
|
+
Y(void 0), J(!0);
|
|
354
|
+
}
|
|
355
|
+
})]
|
|
356
|
+
}), /* @__PURE__ */ O("div", {
|
|
357
|
+
id: ze,
|
|
358
|
+
role: "tree",
|
|
359
|
+
"aria-label": X.filesTreeAriaLabel ?? "Skill files",
|
|
360
|
+
children: /* @__PURE__ */ O(i, {
|
|
361
|
+
items: Fe,
|
|
362
|
+
showFiles: !0,
|
|
363
|
+
selectedPath: G,
|
|
364
|
+
expandedPaths: we,
|
|
365
|
+
onExpandedPathsChange: Te,
|
|
366
|
+
onItemClick: Ie,
|
|
367
|
+
getContextMenuItems: Re,
|
|
368
|
+
rootItemPath: ""
|
|
369
|
+
})
|
|
370
|
+
})]
|
|
371
|
+
}), He = b ? X.savingStatusLabel ?? "Saving" : "", Ue = /* @__PURE__ */ k(D, { children: [/* @__PURE__ */ O(l, {
|
|
372
|
+
label: X.cancelLabel ?? "Cancel",
|
|
373
|
+
onClick: de,
|
|
374
|
+
disabled: b
|
|
375
|
+
}), /* @__PURE__ */ O(m, {
|
|
376
|
+
label: X.createLabel ?? "Create",
|
|
377
|
+
iconBefore: b ? /* @__PURE__ */ O(h, {
|
|
378
|
+
size: 16,
|
|
379
|
+
ariaLabel: ""
|
|
380
|
+
}) : void 0,
|
|
381
|
+
onClick: () => ue(U),
|
|
382
|
+
disabled: b
|
|
383
|
+
})] });
|
|
384
|
+
return re ? /* @__PURE__ */ O("div", {
|
|
385
|
+
className: "flex h-full items-center justify-center",
|
|
386
|
+
children: /* @__PURE__ */ O(h, { ariaLabel: X.loadingAriaLabel ?? "Loading skill" })
|
|
387
|
+
}) : v ? /* @__PURE__ */ k("div", {
|
|
388
|
+
role: "alert",
|
|
389
|
+
className: "flex flex-col items-center gap-4 p-8",
|
|
390
|
+
children: [/* @__PURE__ */ O(c, { text: X.loadErrorMessage ?? "Couldn't load this skill. Please try again." }), /* @__PURE__ */ O(m, {
|
|
391
|
+
label: X.retryLabel ?? "Retry",
|
|
392
|
+
onClick: fe
|
|
393
|
+
})]
|
|
394
|
+
}) : /* @__PURE__ */ k("div", {
|
|
395
|
+
dir: me,
|
|
396
|
+
className: "relative flex h-full flex-col",
|
|
397
|
+
style: Pe,
|
|
398
|
+
...Ae,
|
|
399
|
+
children: [
|
|
400
|
+
/* @__PURE__ */ O(se, {
|
|
401
|
+
isVisible: ke && !q,
|
|
402
|
+
labels: H
|
|
403
|
+
}),
|
|
404
|
+
/* @__PURE__ */ O("span", {
|
|
405
|
+
role: "status",
|
|
406
|
+
"aria-live": "polite",
|
|
407
|
+
className: "sr-only",
|
|
408
|
+
id: Be,
|
|
409
|
+
children: He
|
|
410
|
+
}),
|
|
411
|
+
N && /* @__PURE__ */ O("div", {
|
|
412
|
+
role: "alert",
|
|
413
|
+
className: "px-4 pt-2",
|
|
414
|
+
children: /* @__PURE__ */ O(c, { text: N })
|
|
415
|
+
}),
|
|
416
|
+
P && /* @__PURE__ */ k("div", {
|
|
417
|
+
role: "alert",
|
|
418
|
+
className: "flex items-center gap-2 px-4 pt-2",
|
|
419
|
+
children: [/* @__PURE__ */ O(c, { text: P.message }), /* @__PURE__ */ O(l, {
|
|
420
|
+
label: X.reloadLatestLabel ?? "Reload latest",
|
|
421
|
+
onClick: F
|
|
422
|
+
})]
|
|
423
|
+
}),
|
|
424
|
+
/* @__PURE__ */ k("div", {
|
|
425
|
+
className: n("hidden items-center justify-between gap-2 border-b px-4 py-2 desktop:flex desktop:px-8 desktop:pb-3 desktop:pt-3", B.headerBorder),
|
|
426
|
+
children: [/* @__PURE__ */ O("div", {
|
|
427
|
+
className: "flex min-w-0 flex-1 items-center gap-2",
|
|
428
|
+
children: z
|
|
429
|
+
}), /* @__PURE__ */ O("div", {
|
|
430
|
+
className: "flex shrink-0 items-center gap-2",
|
|
431
|
+
children: Ue
|
|
432
|
+
})]
|
|
433
|
+
}),
|
|
434
|
+
/* @__PURE__ */ k("div", {
|
|
435
|
+
className: "flex flex-1 flex-col gap-4 overflow-y-auto px-4 pb-20 desktop:flex-row desktop:gap-0 desktop:px-0 desktop:pb-0",
|
|
436
|
+
children: [
|
|
437
|
+
/* @__PURE__ */ O("div", {
|
|
438
|
+
className: "desktop:hidden",
|
|
439
|
+
children: /* @__PURE__ */ O(a, {
|
|
440
|
+
title: X.editingFileLabel ?? "Editing file",
|
|
441
|
+
description: $?.name ?? "SKILL.md",
|
|
442
|
+
expanded: De,
|
|
443
|
+
onToggle: Oe,
|
|
444
|
+
ariaLabel: X.editingFileLabel ?? "Editing file",
|
|
445
|
+
children: Ve
|
|
446
|
+
})
|
|
447
|
+
}),
|
|
448
|
+
/* @__PURE__ */ O("div", {
|
|
449
|
+
className: n("hidden border-e desktop:block desktop:w-[360px] desktop:shrink-0 desktop:px-8 desktop:py-6", B.sidebarBorder),
|
|
450
|
+
children: Ve
|
|
451
|
+
}),
|
|
452
|
+
/* @__PURE__ */ k("div", {
|
|
453
|
+
className: "flex min-w-0 flex-1 flex-col gap-4 desktop:gap-5 desktop:px-8 desktop:py-6",
|
|
454
|
+
children: [/* @__PURE__ */ O("h2", {
|
|
455
|
+
className: n(B.title, je),
|
|
456
|
+
children: G === "SKILL.md" ? j : X.selectedFileHeading?.($?.name ?? G) ?? $?.name ?? G
|
|
457
|
+
}), G === "SKILL.md" ? /* @__PURE__ */ k(D, { children: [
|
|
458
|
+
/* @__PURE__ */ O(u, {
|
|
459
|
+
labelProps: {
|
|
460
|
+
label: X.nameLabel ?? "Name",
|
|
461
|
+
required: !0
|
|
462
|
+
},
|
|
463
|
+
value: U.name,
|
|
464
|
+
onChange: (e) => W((t) => ({
|
|
465
|
+
...t,
|
|
466
|
+
name: e ?? ""
|
|
467
|
+
})),
|
|
468
|
+
placeholder: X.namePlaceholder ?? "good-morning-breakfast",
|
|
469
|
+
caption: A?.name ? void 0 : X.nameCaption ?? "Lowercase letters and hyphens only, no spaces. We'll reformat automatically if needed.",
|
|
470
|
+
error: A?.name,
|
|
471
|
+
invalid: !!A?.name,
|
|
472
|
+
disabled: I
|
|
473
|
+
}),
|
|
474
|
+
/* @__PURE__ */ O(g, {
|
|
475
|
+
labelProps: {
|
|
476
|
+
label: X.descriptionLabel ?? "Description",
|
|
477
|
+
required: !0
|
|
478
|
+
},
|
|
479
|
+
value: U.description,
|
|
480
|
+
placeholder: X.descriptionPlaceholder ?? "What this skill does and when to use it",
|
|
481
|
+
onChange: (e) => W((t) => ({
|
|
482
|
+
...t,
|
|
483
|
+
description: e
|
|
484
|
+
})),
|
|
485
|
+
error: A?.description,
|
|
486
|
+
invalid: !!A?.description
|
|
487
|
+
}),
|
|
488
|
+
/* @__PURE__ */ k("div", {
|
|
489
|
+
className: "flex flex-1 flex-col gap-2",
|
|
490
|
+
children: [
|
|
491
|
+
/* @__PURE__ */ k("span", {
|
|
492
|
+
className: "flex items-center gap-0.5",
|
|
493
|
+
children: [/* @__PURE__ */ O("span", {
|
|
494
|
+
className: n(B.helperText, Me),
|
|
495
|
+
children: X.instructionsLabel ?? "Instructions"
|
|
496
|
+
}), /* @__PURE__ */ O("span", {
|
|
497
|
+
className: "dial-tiny-text text-error",
|
|
498
|
+
children: "*"
|
|
499
|
+
})]
|
|
500
|
+
}),
|
|
501
|
+
/* @__PURE__ */ O(y, {
|
|
502
|
+
fallback: /* @__PURE__ */ O(h, { ariaLabel: X.instructionsLoadingAriaLabel ?? "Loading" }),
|
|
503
|
+
children: /* @__PURE__ */ O(le, {
|
|
504
|
+
value: U.instructions,
|
|
505
|
+
onChange: (e) => W((t) => ({
|
|
506
|
+
...t,
|
|
507
|
+
instructions: e
|
|
508
|
+
})),
|
|
509
|
+
theme: he,
|
|
510
|
+
placeholder: X.instructionsPlaceholder ?? "Write the skill instructions in Markdown"
|
|
511
|
+
})
|
|
512
|
+
}),
|
|
513
|
+
A?.instructions && /* @__PURE__ */ O(c, { text: A.instructions })
|
|
514
|
+
]
|
|
515
|
+
})
|
|
516
|
+
] }) : $?.kind === M.File && (V ?? /* @__PURE__ */ O(ee, { text: X.supportingFileNote ?? "This supporting file is included in the skill package as-is. Remove it from the Files panel to replace its content." }))]
|
|
517
|
+
})
|
|
518
|
+
]
|
|
519
|
+
}),
|
|
520
|
+
/* @__PURE__ */ O("div", {
|
|
521
|
+
className: n("fixed inset-x-0 bottom-0 flex items-center gap-2 border-t p-3 desktop:hidden", B.actionBarBorder),
|
|
522
|
+
children: Ue
|
|
523
|
+
}),
|
|
524
|
+
/* @__PURE__ */ O(ce, {
|
|
525
|
+
isOpen: q,
|
|
526
|
+
onClose: () => {
|
|
527
|
+
J(!1), Y(void 0);
|
|
528
|
+
},
|
|
529
|
+
fileActions: R,
|
|
530
|
+
initialFiles: Ee,
|
|
531
|
+
labels: H
|
|
532
|
+
})
|
|
533
|
+
]
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
//#endregion
|
|
537
|
+
export { V as SkillEditor, F as SkillFileCandidateKind, M as SkillFileNodeKind, I as SkillFileValidationStatus };
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { EditorThemes } from '@epam/ai-dial-ui-kit';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { SkillFileNodeKind } from '../types/skill-file-node-kind';
|
|
4
|
+
/**
|
|
5
|
+
* One supporting file or folder in the skill's file tree. The mandatory root
|
|
6
|
+
* `SKILL.md` manifest node is synthesised internally by `SkillEditor` and is
|
|
7
|
+
* never part of this list.
|
|
8
|
+
*/
|
|
9
|
+
export interface SkillFileTreeNode {
|
|
10
|
+
/** Relative path from the skill root, using `/` separators. */
|
|
11
|
+
path: string;
|
|
12
|
+
/** Display name — the final path segment. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Whether this node is a file or a folder. */
|
|
15
|
+
kind: SkillFileNodeKind;
|
|
16
|
+
}
|
|
17
|
+
/** The skill fields the editor form holds. */
|
|
18
|
+
export interface SkillEditorValues {
|
|
19
|
+
/** Skill name, as typed by the user (host normalizes it on submit). */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Short description of what the skill does. */
|
|
22
|
+
description: string;
|
|
23
|
+
/** The skill's instructions body (Markdown). */
|
|
24
|
+
instructions: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Inline validation messages, keyed by field. Resolved by the host, which owns
|
|
28
|
+
* the DIAL naming/storage contract the values must satisfy.
|
|
29
|
+
*/
|
|
30
|
+
export interface SkillEditorErrors {
|
|
31
|
+
/** Message shown under the Name field. */
|
|
32
|
+
name?: string;
|
|
33
|
+
/** Message shown under the Description field. */
|
|
34
|
+
description?: string;
|
|
35
|
+
/** Message shown under the Instructions editor. */
|
|
36
|
+
instructions?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Whether a staged upload candidate is the Skill manifest or an ordinary supporting file. */
|
|
39
|
+
export declare enum SkillFileCandidateKind {
|
|
40
|
+
/** An ordinary supporting file, added to the tree on commit. */
|
|
41
|
+
SupportingFile = "supporting-file",
|
|
42
|
+
/** The root `SKILL.md` manifest, handled by the host as a metadata import rather than a tree entry. */
|
|
43
|
+
Manifest = "manifest"
|
|
44
|
+
}
|
|
45
|
+
/** Whether a staged upload candidate's latest host validation passed. */
|
|
46
|
+
export declare enum SkillFileValidationStatus {
|
|
47
|
+
/** The candidate may be included in a commit. */
|
|
48
|
+
Valid = "valid",
|
|
49
|
+
/** The candidate is blocked from commit; see the result's `error`. */
|
|
50
|
+
Invalid = "invalid"
|
|
51
|
+
}
|
|
52
|
+
/** One file staged in the upload dialog, not yet committed to the editor. */
|
|
53
|
+
export interface SkillFileUploadCandidate {
|
|
54
|
+
/** Stable id for React keys and remove targeting, independent of path edits. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** The raw selected or dropped file. */
|
|
57
|
+
file: File;
|
|
58
|
+
/** Resolved relative path (`webkitRelativePath` falling back to `File.name`, `/`-normalized). */
|
|
59
|
+
path: string;
|
|
60
|
+
}
|
|
61
|
+
/** Host validation outcome for one staged candidate. */
|
|
62
|
+
export interface SkillFileValidationResult {
|
|
63
|
+
/** The `SkillFileUploadCandidate.id` this result applies to. */
|
|
64
|
+
candidateId: string;
|
|
65
|
+
/** Whether the candidate currently passes host validation. */
|
|
66
|
+
status: SkillFileValidationStatus;
|
|
67
|
+
/** Whether this candidate is the Skill manifest or an ordinary supporting file. */
|
|
68
|
+
kind: SkillFileCandidateKind;
|
|
69
|
+
/** Error message to render on the candidate's row. Present when `status` is `Invalid`. */
|
|
70
|
+
error?: string;
|
|
71
|
+
}
|
|
72
|
+
/** A validation problem attributable to the whole staged batch, not one row (e.g. total size/count). */
|
|
73
|
+
export interface SkillFileBatchError {
|
|
74
|
+
/** Message rendered in the dialog's batch-level error region. */
|
|
75
|
+
message: string;
|
|
76
|
+
}
|
|
77
|
+
/** Outcome of committing a staged batch to the editor. */
|
|
78
|
+
export interface SkillFileCommitResult {
|
|
79
|
+
/** Present when the commit failed; the dialog stays open with the batch intact and shows this message. */
|
|
80
|
+
error?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Host-owned operations on the in-memory supporting-file set. The library
|
|
84
|
+
* calls these when the user stages files in the upload dialog or removes an
|
|
85
|
+
* entry; it never mutates `files` itself.
|
|
86
|
+
*/
|
|
87
|
+
export interface SkillEditorFileActions {
|
|
88
|
+
/**
|
|
89
|
+
* Validates the complete currently staged batch. Called on every staged-set
|
|
90
|
+
* change and again immediately before a commit. Never mutates any state.
|
|
91
|
+
*/
|
|
92
|
+
validateBatch: (candidates: SkillFileUploadCandidate[]) => Promise<{
|
|
93
|
+
/** One result per candidate, in the same order as `candidates`. */
|
|
94
|
+
results: SkillFileValidationResult[];
|
|
95
|
+
/** Errors attributable to the batch as a whole. */
|
|
96
|
+
batchErrors: SkillFileBatchError[];
|
|
97
|
+
}>;
|
|
98
|
+
/**
|
|
99
|
+
* Called once, with the full currently-valid staged batch, when the user
|
|
100
|
+
* confirms the upload dialog. Resolves without an `error` to close the
|
|
101
|
+
* dialog and clear staged state; resolves with an `error` to keep the
|
|
102
|
+
* dialog open with the batch intact.
|
|
103
|
+
*/
|
|
104
|
+
commitBatch: (candidates: SkillFileUploadCandidate[]) => Promise<SkillFileCommitResult>;
|
|
105
|
+
/** Called after the user confirms removing a non-protected node already present in the tree. */
|
|
106
|
+
onRemoveNode: (path: string) => void;
|
|
107
|
+
}
|
|
108
|
+
/** Text overrides for `SkillEditor`. Every field has an English default. */
|
|
109
|
+
export interface SkillEditorLabels {
|
|
110
|
+
/** Files pane heading. Defaults to `'Files'`. */
|
|
111
|
+
filesHeading?: string;
|
|
112
|
+
/** Accessible name of the file tree region. Defaults to `'Skill files'`. */
|
|
113
|
+
filesTreeAriaLabel?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Label of the control that opens the device file picker to add a
|
|
116
|
+
* supporting file. Defaults to `'Upload from device'`.
|
|
117
|
+
*/
|
|
118
|
+
addUploadLabel?: string;
|
|
119
|
+
/** Accessible label of a node's remove action. Defaults to `'Remove'`. */
|
|
120
|
+
removeLabel?: string;
|
|
121
|
+
/** Collapsed mobile summary label. Defaults to `'Editing file'`. */
|
|
122
|
+
editingFileLabel?: string;
|
|
123
|
+
/** Main-pane heading, given the selected node's name. Defaults to the name itself. */
|
|
124
|
+
selectedFileHeading?: (name: string) => string;
|
|
125
|
+
/** Name field label. Defaults to `'Name'`. */
|
|
126
|
+
nameLabel?: string;
|
|
127
|
+
/** Name field placeholder. Defaults to `'good-morning-breakfast'`. */
|
|
128
|
+
namePlaceholder?: string;
|
|
129
|
+
/** Name field helper text. Defaults to `"Lowercase letters and hyphens only, no spaces. We'll reformat automatically if needed."`. */
|
|
130
|
+
nameCaption?: string;
|
|
131
|
+
/** Description field label. Defaults to `'Description'`. */
|
|
132
|
+
descriptionLabel?: string;
|
|
133
|
+
/** Description field placeholder. Defaults to `'What this skill does and when to use it'`. */
|
|
134
|
+
descriptionPlaceholder?: string;
|
|
135
|
+
/** Instructions editor label. Defaults to `'Instructions'`. */
|
|
136
|
+
instructionsLabel?: string;
|
|
137
|
+
/** Instructions editor placeholder. Defaults to `'Write the skill instructions in Markdown'`. */
|
|
138
|
+
instructionsPlaceholder?: string;
|
|
139
|
+
/** Create button label. Defaults to `'Create'`. */
|
|
140
|
+
createLabel?: string;
|
|
141
|
+
/** Cancel button label. Defaults to `'Cancel'`. */
|
|
142
|
+
cancelLabel?: string;
|
|
143
|
+
/** Retry button label shown in the load-error state. Defaults to `'Retry'`. */
|
|
144
|
+
retryLabel?: string;
|
|
145
|
+
/** Message shown when the skill could not be loaded. Defaults to `"Couldn't load this skill. Please try again."`. */
|
|
146
|
+
loadErrorMessage?: string;
|
|
147
|
+
/** Status announced while a save is in flight. Defaults to `'Saving'`. */
|
|
148
|
+
savingStatusLabel?: string;
|
|
149
|
+
/** Accessible label of the top-level loading spinner shown while `isLoading` is `true`. Defaults to `'Loading skill'`. */
|
|
150
|
+
loadingAriaLabel?: string;
|
|
151
|
+
/** Accessible label of the spinner shown while the Instructions Markdown editor's chunk is loading. Defaults to `'Loading'`. */
|
|
152
|
+
instructionsLoadingAriaLabel?: string;
|
|
153
|
+
/** Note shown in the main pane when a supporting file (not `SKILL.md` or a folder) is selected. Defaults to a sentence explaining content isn't editable here. */
|
|
154
|
+
supportingFileNote?: string;
|
|
155
|
+
/** Label of the "Reload latest" button rendered next to the host-supplied `conflict.message` in the conflict state. Defaults to `'Reload latest'`. */
|
|
156
|
+
reloadLatestLabel?: string;
|
|
157
|
+
/** Upload dialog title. Defaults to `'Upload files from device'`. */
|
|
158
|
+
uploadDialogTitle?: string;
|
|
159
|
+
/** Accessible label of the upload dialog's close control. Defaults to `'Close'`. */
|
|
160
|
+
uploadDialogCloseAriaLabel?: string;
|
|
161
|
+
/** Drop-zone copy shown at the `desktop` breakpoint. Defaults to `'Drag and drop it or click here to upload'`. */
|
|
162
|
+
uploadDropZoneLabel?: string;
|
|
163
|
+
/** Drop-zone copy shown at the `mobile` breakpoint (no drag surface). Defaults to `'Click here to upload'`. */
|
|
164
|
+
uploadDropZoneMobileLabel?: string;
|
|
165
|
+
/** Accessible label of the drop zone / native-picker trigger. Defaults to `'Upload files'`. */
|
|
166
|
+
uploadDropZoneAriaLabel?: string;
|
|
167
|
+
/** Builds the accessible label of a staged row's remove control, given its path. Defaults to a sentence naming the path. */
|
|
168
|
+
uploadRemoveCandidateLabel?: (path: string) => string;
|
|
169
|
+
/** Explanatory copy on a manifest-kind staged row. Defaults to a sentence explaining it will populate/replace the Skill's metadata. */
|
|
170
|
+
uploadManifestRowNote?: string;
|
|
171
|
+
/** Confirm ("Add"/"Upload") button label in the upload dialog. Defaults to `'Add'`. */
|
|
172
|
+
uploadConfirmLabel?: string;
|
|
173
|
+
/** Cancel button label in the upload dialog. Defaults to `'Cancel'`. */
|
|
174
|
+
uploadCancelLabel?: string;
|
|
175
|
+
/** Prefix announced in the `aria-live` region when a batch-level error appears. Defaults to `'Upload error: '`. */
|
|
176
|
+
uploadBatchErrorAriaPrefix?: string;
|
|
177
|
+
/** Title shown in the full-surface overlay while a file-bearing drag is over the editor and the upload dialog isn't open yet. Defaults to `'Upload files'`. */
|
|
178
|
+
dropOverlayTitle?: string;
|
|
179
|
+
/** Subtitle shown below `dropOverlayTitle`. Defaults to `'Drop files here to add them to this skill'`. */
|
|
180
|
+
dropOverlaySubtitle?: string;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Describes a save-time conflict (e.g. a stale ETag) distinct from
|
|
184
|
+
* `submitError` (an unrecoverable submit failure). When present, `SkillEditor`
|
|
185
|
+
* renders `conflict.message` plus a "Reload latest" control that calls
|
|
186
|
+
* `onReloadLatest` — the control never clears any field itself.
|
|
187
|
+
*/
|
|
188
|
+
export interface SkillEditorConflict {
|
|
189
|
+
/** Host-resolved, already-translated conflict message. */
|
|
190
|
+
message: string;
|
|
191
|
+
}
|
|
192
|
+
/** CSS custom-property color overrides for `SkillEditor`. */
|
|
193
|
+
export interface SkillEditorColors {
|
|
194
|
+
/** Color of the "Files" and selected-file section headings. Defaults to `--text-primary`. */
|
|
195
|
+
title?: string;
|
|
196
|
+
/** Color of the hand-rendered Instructions field label. Defaults to `--text-secondary`. */
|
|
197
|
+
helperText?: string;
|
|
198
|
+
/** Border color of the desktop header row, the Files sidebar divider, and the mobile sticky action bar. Defaults to `--stroke-tertiary`. */
|
|
199
|
+
border?: string;
|
|
200
|
+
}
|
|
201
|
+
/** Typography class overrides for `SkillEditor`. */
|
|
202
|
+
export interface SkillEditorTypography {
|
|
203
|
+
/** Typography class applied to the "Files" and selected-file section headings. Defaults to `'dial-body-semi-text'`. */
|
|
204
|
+
titleClassName?: string;
|
|
205
|
+
/** Typography class applied to the hand-rendered Instructions field label. Defaults to `'dial-tiny-semi-text'`. */
|
|
206
|
+
helperTextClassName?: string;
|
|
207
|
+
/** Color class applied to the file tree "Remove" context-menu icon. Defaults to `'text-secondary'`. */
|
|
208
|
+
removeIconClassName?: string;
|
|
209
|
+
}
|
|
210
|
+
/** Grouped style overrides for `SkillEditor`. */
|
|
211
|
+
export interface SkillEditorStyles {
|
|
212
|
+
/** Color overrides, applied as CSS custom properties. */
|
|
213
|
+
colors?: SkillEditorColors;
|
|
214
|
+
/** Typography class overrides. */
|
|
215
|
+
typography?: SkillEditorTypography;
|
|
216
|
+
}
|
|
217
|
+
/** Props for `SkillEditor`. */
|
|
218
|
+
export interface SkillEditorProps {
|
|
219
|
+
/**
|
|
220
|
+
* Values to seed the fields with. Changing this object's identity re-seeds
|
|
221
|
+
* the form, so hosts that load asynchronously should memoise it and only
|
|
222
|
+
* produce a new object once the data has arrived.
|
|
223
|
+
*/
|
|
224
|
+
initialValues?: Partial<SkillEditorValues>;
|
|
225
|
+
/** Supporting files/folders, excluding the always-present root `SKILL.md` node, which the component synthesises. */
|
|
226
|
+
files: SkillFileTreeNode[];
|
|
227
|
+
/** Currently selected node path. Defaults to `'SKILL.md'` when omitted. */
|
|
228
|
+
selectedPath?: string;
|
|
229
|
+
/** Called when the selected node changes. Omit to let the component manage selection internally. */
|
|
230
|
+
onSelectedPathChange?: (path: string) => void;
|
|
231
|
+
/** Currently expanded folder paths. Omit to let the component manage expansion internally. */
|
|
232
|
+
expandedPaths?: string[];
|
|
233
|
+
/** Called when the set of expanded folder paths changes. */
|
|
234
|
+
onExpandedPathsChange?: (paths: string[]) => void;
|
|
235
|
+
/** Whether the skill being edited is still loading. Defaults to `false`. */
|
|
236
|
+
isLoading?: boolean;
|
|
237
|
+
/** Whether loading the skill failed; renders an error state with a retry instead of the form. Defaults to `false`. */
|
|
238
|
+
hasLoadError?: boolean;
|
|
239
|
+
/** Whether a save is in flight; disables submission. Defaults to `false`. */
|
|
240
|
+
isSubmitting?: boolean;
|
|
241
|
+
/** Inline validation messages to render under the fields. */
|
|
242
|
+
errors?: SkillEditorErrors;
|
|
243
|
+
/** General submit-time error (e.g. a naming conflict or a server error) rendered in a `role="alert"` region. */
|
|
244
|
+
submitError?: string;
|
|
245
|
+
/**
|
|
246
|
+
* A save-time conflict (e.g. a stale ETag), distinct from `submitError`.
|
|
247
|
+
* When present, renders `conflict.message` plus a "Reload latest" control
|
|
248
|
+
* calling `onReloadLatest`. Omit when there is no conflict.
|
|
249
|
+
*/
|
|
250
|
+
conflict?: SkillEditorConflict;
|
|
251
|
+
/** Called when the conflict state's "Reload latest" control is activated. Required when `conflict` can be set. */
|
|
252
|
+
onReloadLatest?: () => void;
|
|
253
|
+
/**
|
|
254
|
+
* When `true`, the Name field renders read-only — its value is still
|
|
255
|
+
* included in submitted values unchanged. The host sets this in edit mode,
|
|
256
|
+
* since DIAL Core has no rename/move operation for a skill; the library
|
|
257
|
+
* itself has no notion of "edit mode" and infers no policy from this flag
|
|
258
|
+
* beyond disabling the field.
|
|
259
|
+
*/
|
|
260
|
+
isNameReadOnly?: boolean;
|
|
261
|
+
/**
|
|
262
|
+
* Called whenever any field value or the file-tree state diverges from its
|
|
263
|
+
* most recently seeded `initialValues`/`files` (`true`), and again once it
|
|
264
|
+
* returns to exactly that seeded state (`false`).
|
|
265
|
+
*/
|
|
266
|
+
onDirtyChange?: (isDirty: boolean) => void;
|
|
267
|
+
/** File-tree mutation operations. */
|
|
268
|
+
fileActions: SkillEditorFileActions;
|
|
269
|
+
/**
|
|
270
|
+
* Host-rendered content (e.g. a back button and page title) placed at the
|
|
271
|
+
* start of the desktop header row, before the Cancel/Create actions. The
|
|
272
|
+
* library renders it verbatim with no knowledge of what it contains.
|
|
273
|
+
*/
|
|
274
|
+
headerContent?: ReactNode;
|
|
275
|
+
/**
|
|
276
|
+
* Host-rendered content shown in the main pane in place of `labels.supportingFileNote`
|
|
277
|
+
* whenever the currently selected node is a supporting file (not `SKILL.md`, not a
|
|
278
|
+
* folder). The library renders it verbatim with no knowledge of what it contains — it
|
|
279
|
+
* only decides *when* to show it, mirroring the `headerContent` pattern. Falls back to
|
|
280
|
+
* `labels.supportingFileNote` when omitted.
|
|
281
|
+
*/
|
|
282
|
+
supportingFileContent?: ReactNode;
|
|
283
|
+
/** Called with the current values when the form is submitted. */
|
|
284
|
+
onSubmit: (values: SkillEditorValues) => void;
|
|
285
|
+
/** Called when the form is dismissed without saving. */
|
|
286
|
+
onCancel: () => void;
|
|
287
|
+
/** Called when the retry button in the load-error state is activated. */
|
|
288
|
+
onRetry?: () => void;
|
|
289
|
+
/** Text overrides. */
|
|
290
|
+
labels?: SkillEditorLabels;
|
|
291
|
+
/** Style overrides. */
|
|
292
|
+
styles?: SkillEditorStyles;
|
|
293
|
+
/** Explicit direction override. Omit to inherit from the ambient `dir` attribute. */
|
|
294
|
+
dir?: 'ltr' | 'rtl';
|
|
295
|
+
/** Theme applied to the Instructions Markdown editor, resolved by the host from its own theme state. Defaults to `EditorThemes.light`. */
|
|
296
|
+
instructionsEditorTheme?: EditorThemes;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=skill-editor-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-editor-props.d.ts","sourceRoot":"","sources":["../../src/models/skill-editor-props.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@epam/ai-dial-skill-editor",
|
|
3
|
+
"description": "Host-agnostic form for authoring a DIAL Skill, with an inline supporting-file tree",
|
|
4
|
+
"version": "1.0.0-rc.5",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./index.js",
|
|
8
|
+
"module": "./index.js",
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
"./package.json": "./package.json",
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"import": "./index.js",
|
|
15
|
+
"default": "./index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@epam/ai-dial-chat-shared": "1.0.0-rc.5",
|
|
20
|
+
"@epam/ai-dial-ui-kit": "^0.13.0-dev.26",
|
|
21
|
+
"@epam/ai-dial-react-file-manager": "^0.1.0-dev.22",
|
|
22
|
+
"@tabler/icons-react": "^3.0.0",
|
|
23
|
+
"react": "^19.0.0"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/epam/ai-dial-chat.git",
|
|
28
|
+
"directory": "libs/skill-editor"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/test-setup.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=test-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-editor-defaults.d.ts","sourceRoot":"","sources":["../../src/types/skill-editor-defaults.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,eAAO,MAAM,mBAAmB,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Kind of entry in the skill's file tree. */
|
|
2
|
+
export declare enum SkillFileNodeKind {
|
|
3
|
+
/** A regular file, including the protected root `SKILL.md`. */
|
|
4
|
+
File = "file",
|
|
5
|
+
/** A grouping folder that may contain other files/folders. */
|
|
6
|
+
Folder = "folder"
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=skill-file-node-kind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-file-node-kind.d.ts","sourceRoot":"","sources":["../../src/types/skill-file-node-kind.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,oBAAY,iBAAiB;IAC3B,+DAA+D;IAC/D,IAAI,SAAS;IACb,8DAA8D;IAC9D,MAAM,WAAW;CAClB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a selected/dropped `File`'s relative path: `webkitRelativePath`
|
|
3
|
+
* when the browser populated it, falling back to `File.name`, with any
|
|
4
|
+
* backslash separator normalized to a forward slash.
|
|
5
|
+
*/
|
|
6
|
+
export declare const resolveCandidatePath: (file: File) => string;
|
|
7
|
+
//# sourceMappingURL=candidate-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-path.d.ts","sourceRoot":"","sources":["../../src/utils/candidate-path.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,IAAI,KAAG,MAKjD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DialFile } from '@epam/ai-dial-react-file-manager';
|
|
2
|
+
import { SkillFileTreeNode } from '../models/skill-editor-props';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the nested `DialFile[]` tree `DialFoldersTree` expects from the flat
|
|
5
|
+
* `SkillFileTreeNode[]` list, synthesising any implicit intermediate folders
|
|
6
|
+
* (e.g. `agents/analyzer.md` implies an `agents` folder even when no explicit
|
|
7
|
+
* folder node was added for it).
|
|
8
|
+
*/
|
|
9
|
+
export declare const buildDialFileTree: (nodes: SkillFileTreeNode[]) => DialFile[];
|
|
10
|
+
//# sourceMappingURL=file-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-tree.d.ts","sourceRoot":"","sources":["../../src/utils/file-tree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAatE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,iBAAiB,EAAE,KAAG,QAAQ,EAuDtE,CAAC"}
|