Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a8235e0
feat(studio): add DevEnv Skill workbench
Aug 4, 2026
a28de4e
fix(studio): support repeat source deployment
Aug 4, 2026
876a4c1
fix(studio): expose background Skill task progress
Aug 5, 2026
dff0c39
fix(vefaas): expose safe upload diagnostics
Aug 5, 2026
12145dd
fix(studio): show DevEnv provisioning progress
Aug 5, 2026
50a55e3
feat(studio): make Skill workbench conversation-first
Aug 5, 2026
2bda734
fix(studio): stage clean source deployment wheel
Aug 5, 2026
afce02e
style: apply repository formatter
Aug 5, 2026
3a3336a
feat(studio): refine Skill workbench experience
Aug 5, 2026
bf4ef4e
fix(studio): harden Skill workbench lifecycle UX
Aug 6, 2026
8836f18
fix(studio): make Skill workbench failures actionable
Aug 6, 2026
842a251
fix(studio): stabilize Skill workbench DevEnv lifecycle
Aug 6, 2026
a6cab32
fix(studio): harden AI-native Skill workbench flow
Aug 6, 2026
193e5d7
fix(studio): harden Skill workbench runtime flow
Aug 6, 2026
19a564f
fix(studio): bind Skill artifacts to immutable revisions
Aug 6, 2026
cb2cfb8
fix(studio): reconcile asynchronous session snapshots
Aug 6, 2026
5c58d68
fix(studio): recover Skill artifacts and chat navigation
Aug 6, 2026
9bc2d5b
fix(studio): finalize expired Skill session handling
Aug 6, 2026
95acf42
fix(studio): isolate Skill refinement revisions
Aug 6, 2026
62fa343
fix(studio): preserve BytePlus sandbox deployment
Aug 6, 2026
7e99ea7
chore(studio): rebuild frontend after main rebase
Aug 6, 2026
2c58bc8
fix(studio): harden Skill delegation contract
Aug 6, 2026
0657d00
test(vefaas): patch active upload client
Aug 6, 2026
26bc0f3
test(vefaas): use structured upload log assertions
Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,18 @@ server that `veadk frontend` launches — no separate backend.
the normal conversation renderer; leaving the conversation only disconnects
it, so the Agent remains available until the user deletes it. OpenClaw and
Hermes expose their main interface and Terminal through Studio.
- **AgentKit Skill center**: browse Skill Spaces and their skills with
server-side pagination by region, then inspect the selected Skill content.
- **AgentKit Skill center**: browse Skill Spaces and complete Skill packages
with server-side pagination by region. A new-chat-style composer starts
create or optimize conversations directly from the center, using either a
selected Skill or an uploaded ZIP as the optimization source. Skill
conversations share the normal sidebar history, preserve DevEnv progress
across navigation, and expose the complete generated file tree in a
read-only browser. Cloud deployment binds the same hosted Ark key and
`doubao-seed-evolving` default Codex model to the chat CodeEnv and Skill
Workbench DevEnv. Publishing streams each AgentKit stage, requires a concrete
Skill Space destination, and links the completed version back to that
destination in the center. Preview, ZIP download, and publishing are bound to
the same immutable revision and content digest.
- **Automation directory**: browse development and message-channel integrations
from the Studio sidebar. The local Coding Agents integration detects Trae,
Claude Code, and Codex across macOS, Linux, and Windows, then globally installs
Expand Down
1 change: 1 addition & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@codemirror/lang-markdown": "^6.5.1",
"@codemirror/lang-python": "^6.2.1",
"@codemirror/lang-yaml": "^6.1.3",
"@codemirror/legacy-modes": "^6.5.3",
"@dagrejs/dagre": "^3.0.0",
"@mdxeditor/editor": "^4.1.0",
"@openai/apps-sdk-ui": "^0.2.2",
Expand Down
94 changes: 92 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ import {
import { Sidebar, type SidebarPage } from "./ui/Sidebar";
import { AgentInfoPanel } from "./ui/AgentTopology";
import { SkillCenterView } from "./ui/SkillCenter";
import { SkillWorkbench } from "./ui/skill-workbench/SkillWorkbench";
import { useSkillWorkbenchTasks } from "./ui/skill-workbench/useSkillWorkbenchTasks";
import type { SkillWorkbenchPublishResult } from "./ui/skill-workbench/types";
import { AddAgentKitView } from "./ui/AddAgentKit";
import { AgentWorkspace } from "./ui/AgentWorkspace";
import {
Expand Down Expand Up @@ -1145,6 +1148,13 @@ export default function App() {
// flashing the notice in the common, configured case).
const [hasCreds, setHasCreds] = useState(true);
const [skillCenter, setSkillCenter] = useState(false);
const [skillWorkbenchOpen, setSkillWorkbenchOpen] = useState(false);
const [skillCenterFocus, setSkillCenterFocus] =
useState<SkillWorkbenchPublishResult | null>(null);
const skillWorkbenchTasks = useSkillWorkbenchTasks(
features.skillCenter !== false,
userId,
);
const [addAgent, setAddAgent] = useState(false);
// The "添加 Agent" chooser (two cards: AgentKit / 从 0 快速创建).
const [addMenu, setAddMenu] = useState(false);
Expand Down Expand Up @@ -1733,6 +1743,7 @@ export default function App() {
setAppName("");
setCreateView(null);
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setAddMenu(false);
setSearchView(false);
Expand Down Expand Up @@ -3015,6 +3026,7 @@ export default function App() {
setPlatformFeedbackOrigin(null);
setCreateView(null);
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setAddMenu(false);
setSearchView(false);
Expand Down Expand Up @@ -3996,6 +4008,7 @@ export default function App() {
setManageAgents(false);
setCreateView(null);
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setAddMenu(false);
setSearchView(false);
Expand Down Expand Up @@ -4191,10 +4204,18 @@ export default function App() {
? "search"
: myAgents || manageAgents || sandboxAgentDetailTarget || sandboxAgentWorkspace
? "agents"
: sessionId || createView || skillCenter || addAgent || addMenu
: sessionId || createView || skillCenter || skillWorkbenchOpen || addAgent || addMenu
? null
: "new-chat";

const deleteSkillConversation = async (jobId: string) => {
await skillWorkbenchTasks.deleteTask(jobId);
if (skillWorkbenchTasks.activeJobId === jobId) {
setSkillWorkbenchOpen(false);
setSkillCenter(true);
}
};

return (
<div className="layout">
<Sidebar
Expand All @@ -4207,12 +4228,38 @@ export default function App() {
activePage={sidebarActivePage}
streamingSids={streamingSids}
evaluatingSids={evaluatingSids}
skillConversations={skillWorkbenchTasks.tasks}
skillConversationsLoading={skillWorkbenchTasks.tasksLoading}
skillConversationsError={skillWorkbenchTasks.tasksError}
activeSkillConversationId={skillWorkbenchOpen ? skillWorkbenchTasks.activeJobId : ""}
onRetrySkillConversations={() => void skillWorkbenchTasks.refreshTasks()}
onDeleteSkillConversation={deleteSkillConversation}
onOpenSkillConversation={(jobId) => {
if (sandboxSession) exitSandboxSession();
viewSidRef.current = "";
setSessionId("");
setCreateView(null);
setAddAgent(false);
setAddMenu(false);
setSearchView(false);
setManageAgents(false);
setAgentDetailTarget(null);
setSandboxAgentDetailTarget(null);
setSandboxAgentWorkspace(null);
setMyAgents(false);
setApplicationsView(null);
setSkillCenter(false);
skillWorkbenchTasks.selectTask(jobId);
setSkillWorkbenchOpen(true);
setError("");
}}
onNewChat={openNewChat}
onSearch={() => {
setPlatformFeedbackOrigin(null);
if (sandboxSession) exitSandboxSession();
setCreateView(null);
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setAddMenu(false);
setManageAgents(false);
Expand All @@ -4234,6 +4281,7 @@ export default function App() {
viewSidRef.current = "";
setSessionId("");
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setSearchView(false);
setManageAgents(false);
Expand All @@ -4260,6 +4308,8 @@ export default function App() {
setSandboxAgentWorkspace(null);
setMyAgents(false);
setApplicationsView(null);
setSkillWorkbenchOpen(false);
setSkillCenterFocus(null);
setSkillCenter(true);
setError("");
}}
Expand Down Expand Up @@ -4302,6 +4352,7 @@ export default function App() {
setPlatformFeedbackOrigin(null);
setCreateView(null);
setSkillCenter(false);
setSkillWorkbenchOpen(false);
setAddAgent(false);
setAddMenu(false);
setSearchView(false);
Expand Down Expand Up @@ -4819,8 +4870,47 @@ export default function App() {
}}
onCancel={() => setAddAgent(false)}
/>
) : skillWorkbenchOpen ? (
<SkillWorkbench
task={skillWorkbenchTasks.activeTask}
provisioningTask={skillWorkbenchTasks.activeProvisioningTask}
taskLoading={skillWorkbenchTasks.activeTaskLoading || skillWorkbenchTasks.startingTask}
taskError={skillWorkbenchTasks.activeTaskError || skillWorkbenchTasks.startError}
taskRecovering={skillWorkbenchTasks.activeTaskRecovering}
artifact={skillWorkbenchTasks.activeArtifact}
artifactLoading={skillWorkbenchTasks.activeArtifactLoading}
artifactError={skillWorkbenchTasks.activeArtifactError}
onTaskChanged={skillWorkbenchTasks.upsertTask}
onCancelProvisioning={skillWorkbenchTasks.cancelProvisioning}
onStopTask={skillWorkbenchTasks.stopTask}
onRetryTask={() => void skillWorkbenchTasks.refreshActiveTask()}
onRetryArtifact={() => {
void skillWorkbenchTasks.refreshActiveArtifact().catch(() => undefined);
}}
onBack={() => {
setSkillWorkbenchOpen(false);
setSkillCenter(true);
}}
onViewPublished={(result) => {
setSkillCenterFocus(result);
setSkillWorkbenchOpen(false);
setSkillCenter(true);
}}
/>
) : skillCenter ? (
<SkillCenterView cloudProvider={cloudProvider} />
<SkillCenterView
cloudProvider={cloudProvider}
focus={skillCenterFocus}
onFocusHandled={() => setSkillCenterFocus(null)}
onStartTask={(args) => {
skillWorkbenchTasks.clearActiveTask();
setSkillCenterFocus(null);
const pending = skillWorkbenchTasks.startTask(args);
setSkillCenter(false);
setSkillWorkbenchOpen(true);
return pending;
}}
/>
) : visibleCreateView !== null && !hasCreds ? (
<div
style={{
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/create/skills/skillspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export interface SkillSpacePageOptions {
project?: string;
}

export function formatSkillVersion(version?: string): string {
const normalized = (version || "").trim().replace(/^v+/i, "");
return normalized ? `v${normalized}` : "—";
}

async function jfetch<T>(url: string): Promise<T> {
const res = await fetch(url, {
headers: { accept: "application/json" },
Expand Down
Loading
Loading