@uniqueli/openwork 0.2.3 → 0.2.4
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/README.md
CHANGED
|
@@ -107,6 +107,19 @@ CUSTOM_MODEL=your-model-name # optional
|
|
|
107
107
|
|
|
108
108
|
## Changelog
|
|
109
109
|
|
|
110
|
+
### v0.2.4 (2026-02-06)
|
|
111
|
+
- ✨ **聊天建议卡片**: 新对话空状态下显示可点击的建议卡片(文件整理、内容创作、文档处理),点击即可快速开始对话
|
|
112
|
+
|
|
113
|
+
### v0.2.3 (2026-02-04)
|
|
114
|
+
- ✨ **Skills System**: 新增技能配置系统,支持 12 个内置技能和自定义技能创建
|
|
115
|
+
- 🐛 修复 `deleteUserSkill` 误删所有技能记录的严重 Bug
|
|
116
|
+
- 🐛 修复 Switch 组件、创建技能对话框、技能过滤等多个问题
|
|
117
|
+
- ⚡ 技能初始化改为懒加载,提升启动性能
|
|
118
|
+
|
|
119
|
+
### v0.2.2 (2026-xx-xx)
|
|
120
|
+
- ✨ 支持多个自定义 API 配置
|
|
121
|
+
- 🔧 动态 Provider 系统
|
|
122
|
+
|
|
110
123
|
### v0.2.1 (2026-01-19)
|
|
111
124
|
- 🐛 **Critical Fix**: Fixed "Missing credentials" error for users without OpenAI API key
|
|
112
125
|
- 🔧 Custom API now works correctly even when OPENAI_API_KEY is not set in environment
|
|
@@ -489,6 +489,10 @@
|
|
|
489
489
|
margin-top: calc(var(--spacing) * 2);
|
|
490
490
|
}
|
|
491
491
|
|
|
492
|
+
.mt-6 {
|
|
493
|
+
margin-top: calc(var(--spacing) * 6);
|
|
494
|
+
}
|
|
495
|
+
|
|
492
496
|
.mr-1 {
|
|
493
497
|
margin-right: calc(var(--spacing) * 1);
|
|
494
498
|
}
|
|
@@ -1434,6 +1438,16 @@
|
|
|
1434
1438
|
}
|
|
1435
1439
|
}
|
|
1436
1440
|
|
|
1441
|
+
.bg-accent\/30 {
|
|
1442
|
+
background-color: var(--accent);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1446
|
+
.bg-accent\/30 {
|
|
1447
|
+
background-color: color-mix(in oklab, var(--accent) 30%, transparent);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1437
1451
|
.bg-amber-500\/5 {
|
|
1438
1452
|
background-color: #f99c000d;
|
|
1439
1453
|
}
|
|
@@ -12785,6 +12785,24 @@ const Music = createLucideIcon("Music", [
|
|
|
12785
12785
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
12786
12786
|
["circle", { cx: "18", cy: "16", r: "3", key: "1hluhg" }]
|
|
12787
12787
|
]);
|
|
12788
|
+
const PenTool = createLucideIcon("PenTool", [
|
|
12789
|
+
[
|
|
12790
|
+
"path",
|
|
12791
|
+
{
|
|
12792
|
+
d: "M15.707 21.293a1 1 0 0 1-1.414 0l-1.586-1.586a1 1 0 0 1 0-1.414l5.586-5.586a1 1 0 0 1 1.414 0l1.586 1.586a1 1 0 0 1 0 1.414z",
|
|
12793
|
+
key: "nt11vn"
|
|
12794
|
+
}
|
|
12795
|
+
],
|
|
12796
|
+
[
|
|
12797
|
+
"path",
|
|
12798
|
+
{
|
|
12799
|
+
d: "m18 13-1.375-6.874a1 1 0 0 0-.746-.776L3.235 2.028a1 1 0 0 0-1.207 1.207L5.35 15.879a1 1 0 0 0 .776.746L13 18",
|
|
12800
|
+
key: "15qc1e"
|
|
12801
|
+
}
|
|
12802
|
+
],
|
|
12803
|
+
["path", { d: "m2.3 2.3 7.286 7.286", key: "1wuzzi" }],
|
|
12804
|
+
["circle", { cx: "11", cy: "11", r: "2", key: "xmgehs" }]
|
|
12805
|
+
]);
|
|
12788
12806
|
const Pencil = createLucideIcon("Pencil", [
|
|
12789
12807
|
[
|
|
12790
12808
|
"path",
|
|
@@ -75841,6 +75859,76 @@ function ContextUsageIndicator({
|
|
|
75841
75859
|
] }) })
|
|
75842
75860
|
] });
|
|
75843
75861
|
}
|
|
75862
|
+
const Card = reactExports.forwardRef(
|
|
75863
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75864
|
+
"div",
|
|
75865
|
+
{
|
|
75866
|
+
ref,
|
|
75867
|
+
className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
|
|
75868
|
+
...props
|
|
75869
|
+
}
|
|
75870
|
+
)
|
|
75871
|
+
);
|
|
75872
|
+
Card.displayName = "Card";
|
|
75873
|
+
const CardHeader = reactExports.forwardRef(
|
|
75874
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
|
|
75875
|
+
);
|
|
75876
|
+
CardHeader.displayName = "CardHeader";
|
|
75877
|
+
const CardTitle = reactExports.forwardRef(
|
|
75878
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
|
|
75879
|
+
);
|
|
75880
|
+
CardTitle.displayName = "CardTitle";
|
|
75881
|
+
const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
75882
|
+
CardDescription.displayName = "CardDescription";
|
|
75883
|
+
const CardContent = reactExports.forwardRef(
|
|
75884
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
|
|
75885
|
+
);
|
|
75886
|
+
CardContent.displayName = "CardContent";
|
|
75887
|
+
const CardFooter = reactExports.forwardRef(
|
|
75888
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
|
|
75889
|
+
);
|
|
75890
|
+
CardFooter.displayName = "CardFooter";
|
|
75891
|
+
const ICON_MAP = {
|
|
75892
|
+
FolderOpen,
|
|
75893
|
+
PenTool,
|
|
75894
|
+
FileText
|
|
75895
|
+
};
|
|
75896
|
+
const DEFAULT_SUGGESTIONS = [
|
|
75897
|
+
{
|
|
75898
|
+
icon: "FolderOpen",
|
|
75899
|
+
title: "文件整理",
|
|
75900
|
+
description: "智能整理和管理本地文件"
|
|
75901
|
+
},
|
|
75902
|
+
{
|
|
75903
|
+
icon: "PenTool",
|
|
75904
|
+
title: "内容创作",
|
|
75905
|
+
description: "创建演示文稿、文档和多媒体内容"
|
|
75906
|
+
},
|
|
75907
|
+
{
|
|
75908
|
+
icon: "FileText",
|
|
75909
|
+
title: "文档处理",
|
|
75910
|
+
description: "处理和分析文档数据"
|
|
75911
|
+
}
|
|
75912
|
+
];
|
|
75913
|
+
function SuggestionCards({ onSelect }) {
|
|
75914
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { "data-testid": "suggestion-cards", className: "grid grid-cols-3 gap-3 mt-6 w-full max-w-lg", children: DEFAULT_SUGGESTIONS.map((suggestion) => {
|
|
75915
|
+
const IconComponent = ICON_MAP[suggestion.icon];
|
|
75916
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75917
|
+
Card,
|
|
75918
|
+
{
|
|
75919
|
+
className: "cursor-pointer transition-colors hover:bg-accent/50",
|
|
75920
|
+
onClick: () => onSelect(suggestion),
|
|
75921
|
+
"data-testid": "suggestion-card",
|
|
75922
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4 flex flex-col items-start gap-2", children: [
|
|
75923
|
+
IconComponent && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg bg-accent/30 p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconComponent, { className: "size-5 text-muted-foreground" }) }),
|
|
75924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold", children: suggestion.title }),
|
|
75925
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: suggestion.description })
|
|
75926
|
+
] })
|
|
75927
|
+
},
|
|
75928
|
+
suggestion.title
|
|
75929
|
+
);
|
|
75930
|
+
}) });
|
|
75931
|
+
}
|
|
75844
75932
|
function ChatContainer({ threadId }) {
|
|
75845
75933
|
const inputRef = reactExports.useRef(null);
|
|
75846
75934
|
const scrollRef = reactExports.useRef(null);
|
|
@@ -76055,11 +76143,33 @@ function ChatContainer({ threadId }) {
|
|
|
76055
76143
|
await selectWorkspaceFolder(threadId, setWorkspacePath, setWorkspaceFiles, () => {
|
|
76056
76144
|
}, void 0);
|
|
76057
76145
|
};
|
|
76146
|
+
const handleSuggestionSelect = async (suggestion) => {
|
|
76147
|
+
if (isLoading || !stream || !workspacePath) return;
|
|
76148
|
+
const message = suggestion.title;
|
|
76149
|
+
const userMessage = {
|
|
76150
|
+
id: crypto.randomUUID(),
|
|
76151
|
+
role: "user",
|
|
76152
|
+
content: message,
|
|
76153
|
+
created_at: /* @__PURE__ */ new Date()
|
|
76154
|
+
};
|
|
76155
|
+
appendMessage(userMessage);
|
|
76156
|
+
const currentThread = threads.find((t) => t.thread_id === threadId);
|
|
76157
|
+
if (currentThread?.title?.startsWith("Thread ")) {
|
|
76158
|
+
generateTitleForFirstMessage(threadId, message);
|
|
76159
|
+
}
|
|
76160
|
+
await stream.submit(
|
|
76161
|
+
{ messages: [{ type: "human", content: message }] },
|
|
76162
|
+
{ config: { configurable: { thread_id: threadId, model_id: currentModel } } }
|
|
76163
|
+
);
|
|
76164
|
+
};
|
|
76058
76165
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
|
|
76059
76166
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", ref: scrollRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-3xl mx-auto space-y-4", children: [
|
|
76060
76167
|
displayMessages.length === 0 && !isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-20 text-muted-foreground", children: [
|
|
76061
76168
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-2", children: "NEW THREAD" }),
|
|
76062
|
-
workspacePath ? /* @__PURE__ */ jsxRuntimeExports.
|
|
76169
|
+
workspacePath ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
76170
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm", children: "Start a conversation with the agent" }),
|
|
76171
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SuggestionCards, { onSelect: handleSuggestionSelect })
|
|
76172
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center space-y-3", children: [
|
|
76063
76173
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
76064
76174
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-500", children: "Select a workspace folder" }),
|
|
76065
76175
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs mt-1 opacity-75", children: "The agent needs a workspace to create and modify files" })
|
|
@@ -77728,35 +77838,6 @@ function KanbanColumn({
|
|
|
77728
77838
|
}
|
|
77729
77839
|
);
|
|
77730
77840
|
}
|
|
77731
|
-
const Card = reactExports.forwardRef(
|
|
77732
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
77733
|
-
"div",
|
|
77734
|
-
{
|
|
77735
|
-
ref,
|
|
77736
|
-
className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
|
|
77737
|
-
...props
|
|
77738
|
-
}
|
|
77739
|
-
)
|
|
77740
|
-
);
|
|
77741
|
-
Card.displayName = "Card";
|
|
77742
|
-
const CardHeader = reactExports.forwardRef(
|
|
77743
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
|
|
77744
|
-
);
|
|
77745
|
-
CardHeader.displayName = "CardHeader";
|
|
77746
|
-
const CardTitle = reactExports.forwardRef(
|
|
77747
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
|
|
77748
|
-
);
|
|
77749
|
-
CardTitle.displayName = "CardTitle";
|
|
77750
|
-
const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
77751
|
-
CardDescription.displayName = "CardDescription";
|
|
77752
|
-
const CardContent = reactExports.forwardRef(
|
|
77753
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
|
|
77754
|
-
);
|
|
77755
|
-
CardContent.displayName = "CardContent";
|
|
77756
|
-
const CardFooter = reactExports.forwardRef(
|
|
77757
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
|
|
77758
|
-
);
|
|
77759
|
-
CardFooter.displayName = "CardFooter";
|
|
77760
77841
|
function ThreadStatusIcon({ threadId }) {
|
|
77761
77842
|
const { isLoading } = useThreadStream(threadId);
|
|
77762
77843
|
if (isLoading) {
|
|
@@ -78120,7 +78201,7 @@ function App() {
|
|
|
78120
78201
|
},
|
|
78121
78202
|
children: [
|
|
78122
78203
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
|
|
78123
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.
|
|
78204
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.4" })
|
|
78124
78205
|
]
|
|
78125
78206
|
}
|
|
78126
78207
|
),
|
package/out/renderer/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
http-equiv="Content-Security-Policy"
|
|
8
8
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
|
9
9
|
/>
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-Be3u7LN6.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/index-B2t12qbx.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|