@oh-story/dsh 0.1.6 → 0.1.8
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 +29 -12
- package/lib/client.js +356 -89
- package/lib/client.js.map +4 -4
- package/lib/drama/manifest.json +34 -34
- package/lib/drama/skills/short-drama/SKILL.md +4 -1
- package/lib/drama/skills/short-drama/references/contract-and-ownership.md +2 -0
- package/lib/drama/skills/short-drama/references/creator-documents.md +30 -4
- package/lib/drama/skills/short-drama/references/creator-workflow.md +8 -2
- package/lib/drama/skills/short-drama/references/reference-roles.md +16 -2
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +328 -48
- package/lib/drama/skills/short-drama-produce/SKILL.md +4 -1
- package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +34 -2
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +27 -5
- package/lib/drama/skills/short-drama-storyboard/references/review-and-fixtures.md +2 -1
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -2
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +11 -2
- package/lib/drama/skills/short-drama-video-prompts/assets/video-prompts.md +6 -1
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +19 -3
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +8 -2
- package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +1 -0
- package/lib/index.js +194 -62
- package/lib/index.js.map +4 -4
- package/lib/types/client/drama-production-view.d.ts +1 -0
- package/lib/types/client/drama-production-view.d.ts.map +1 -1
- package/lib/types/client/drama-production.d.ts +3 -0
- package/lib/types/client/drama-production.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/video-studio.d.ts +2 -1
- package/lib/types/client/video-studio.d.ts.map +1 -1
- package/lib/types/client/workbench-presence.d.ts +29 -0
- package/lib/types/client/workbench-presence.d.ts.map +1 -0
- package/lib/types/drama-adapters.d.ts +65 -0
- package/lib/types/drama-adapters.d.ts.map +1 -0
- package/lib/types/host-python.d.ts +19 -0
- package/lib/types/host-python.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/types/workspace-route.d.ts.map +1 -1
- package/package.json +41 -41
package/lib/client.js
CHANGED
|
@@ -560,10 +560,11 @@ function parseEpisodeProduction(documents, episodeDirectory) {
|
|
|
560
560
|
let storyboardPath = `${episodeDirectory}/\u5206\u955C.md`, imagePromptPath = `${episodeDirectory}/\u56FE\u7247\u63D0\u793A\u8BCD.md`, videoPromptPath = `${episodeDirectory}/\u89C6\u9891\u63D0\u793A\u8BCD.md`, visualPath = `${episodeDirectory}/\u89C6\u89C9\u8BBE\u5B9A.md`, shots = parseStoryboard(storyboardPath, documents[storyboardPath] ?? ""), assets = parseImagePrompts(imagePromptPath, documents[imagePromptPath] ?? ""), motions = parseVideoPrompts(videoPromptPath, documents[videoPromptPath] ?? ""), visualAssets = parseVisualAssets(visualPath, documents[visualPath] ?? ""), motionByShot = new Map(motions.flatMap((motion) => motion.shotId === void 0 ? [] : [[motion.shotId, motion]])), linkedShots = shots.map((shot) => ({ ...shot, motion: motionByShot.get(shot.id) })), targets = /* @__PURE__ */ new Map();
|
|
561
561
|
for (let item of [...linkedShots, ...assets, ...motions, ...visualAssets])
|
|
562
562
|
targets.set(item.id, { path: item.path, offset: item.offset, id: item.id });
|
|
563
|
+
let screenplayPath = `${episodeDirectory}/\u5267\u672C.md`;
|
|
563
564
|
for (let shot of linkedShots)
|
|
564
|
-
|
|
565
|
-
let
|
|
566
|
-
target !== void 0 && targets.set(
|
|
565
|
+
for (let id of sourceKeys(shot)) {
|
|
566
|
+
let target = sectionTarget(screenplayPath, documents[screenplayPath] ?? "", id);
|
|
567
|
+
target !== void 0 && targets.set(id, target);
|
|
567
568
|
}
|
|
568
569
|
let diagnostics = validateProductionProtocol({
|
|
569
570
|
documents,
|
|
@@ -589,13 +590,14 @@ function parseStoryboard(path, content) {
|
|
|
589
590
|
return levelTwoSections(content).flatMap((section) => {
|
|
590
591
|
let match = /^(SHOT-[A-Z0-9-]+)\s*(?:[·||]\s*)?(.*)$/iu.exec(section.heading.trim());
|
|
591
592
|
if (match === null || match[1] === void 0) return [];
|
|
592
|
-
let fields = bulletFields(section.body), id = match[1].toLocaleUpperCase();
|
|
593
|
+
let fields = bulletFields(section.body), id = match[1].toLocaleUpperCase(), source = firstField(fields, "\u6765\u6E90", "\u573A\u6B21");
|
|
593
594
|
return [{
|
|
594
595
|
id,
|
|
595
596
|
title: match[2]?.trim() || id,
|
|
596
597
|
path,
|
|
597
598
|
offset: section.offset,
|
|
598
|
-
source
|
|
599
|
+
source,
|
|
600
|
+
sceneIds: sourceSceneIds(source),
|
|
599
601
|
durationSeconds: seconds(firstField(fields, "\u65F6\u957F")),
|
|
600
602
|
purpose: firstField(fields, "\u76EE\u7684", "\u955C\u5934\u76EE\u7684"),
|
|
601
603
|
shotSpec: firstField(fields, "\u666F\u522B/\u673A\u4F4D", "\u666F\u522B", "\u955C\u5934\u89C4\u683C"),
|
|
@@ -663,7 +665,8 @@ function validateProductionProtocol(input) {
|
|
|
663
665
|
for (let shot of input.shots) {
|
|
664
666
|
for (let reference of shot.references)
|
|
665
667
|
knownReferences.has(reference) || add({ severity: "warning", code: "unknown_reference", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u5F15\u7528\u4E86\u672A\u89E3\u6790\u7684 ${reference}\u3002` });
|
|
666
|
-
|
|
668
|
+
for (let id of sourceKeys(shot))
|
|
669
|
+
sectionTarget(screenplayPath, input.documents[screenplayPath] ?? "", id) === void 0 && add({ severity: "warning", code: "unknown_source", path: shot.path, offset: shot.offset, targetId: shot.id, message: `${shot.id} \u7684\u6765\u6E90 ${id} \u5728\u5267\u672C\u4E2D\u4E0D\u5B58\u5728\u3002` });
|
|
667
670
|
}
|
|
668
671
|
let shots = new Set(input.shots.map((shot) => shot.id)), motionsByShot = /* @__PURE__ */ new Map();
|
|
669
672
|
for (let motion of input.motions) {
|
|
@@ -739,6 +742,12 @@ function slug(value) {
|
|
|
739
742
|
function lineAt(content, offset) {
|
|
740
743
|
return content.slice(0, Math.max(0, offset)).split(/\r?\n/u).length;
|
|
741
744
|
}
|
|
745
|
+
function sourceSceneIds(source) {
|
|
746
|
+
return source === void 0 ? [] : [...new Set([...source.matchAll(/(?:[A-Za-z0-9]+-)+SC[0-9]+/gu)].map((match) => match[0]))];
|
|
747
|
+
}
|
|
748
|
+
function sourceKeys(shot) {
|
|
749
|
+
return shot.sceneIds.length > 0 ? shot.sceneIds : shot.source === void 0 ? [] : [shot.source];
|
|
750
|
+
}
|
|
742
751
|
function sectionTarget(path, content, id) {
|
|
743
752
|
let offset = content.search(new RegExp(`^##\\s+${id.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")}(?:\\s|$)`, "imu"));
|
|
744
753
|
return offset < 0 ? void 0 : { path, offset, id };
|
|
@@ -751,6 +760,19 @@ function creatorDocumentOrder(path) {
|
|
|
751
760
|
// src/client/drama-production-view.tsx
|
|
752
761
|
var import_react = require("react");
|
|
753
762
|
|
|
763
|
+
// src/client/workbench-ui.ts
|
|
764
|
+
function handleTabKey(event, values, current, select) {
|
|
765
|
+
let index;
|
|
766
|
+
if (event.key === "Home" ? index = 0 : event.key === "End" ? index = values.length - 1 : event.key === "ArrowRight" ? index = (values.indexOf(current) + 1) % values.length : event.key === "ArrowLeft" && (index = (values.indexOf(current) - 1 + values.length) % values.length), index === void 0) return;
|
|
767
|
+
event.preventDefault();
|
|
768
|
+
let value = values[index];
|
|
769
|
+
value !== void 0 && (select(value), event.currentTarget.parentElement?.querySelectorAll("[role='tab']")[index]?.focus());
|
|
770
|
+
}
|
|
771
|
+
function endpoint(path, sessionId, file) {
|
|
772
|
+
let url = new URL(`/oh-story/${path}`, globalThis.location.origin);
|
|
773
|
+
return url.searchParams.set("sessionId", sessionId), file !== void 0 && url.searchParams.set("path", file), url.toString();
|
|
774
|
+
}
|
|
775
|
+
|
|
754
776
|
// src/client/production-prompts.ts
|
|
755
777
|
var authorityBoundary = "\u53EA\u4F7F\u7528\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u5DE5\u5177\uFF1B\u6240\u6709\u6587\u4EF6\u3001\u7F51\u7EDC\u3001\u751F\u6210\u548C\u547D\u4EE4\u64CD\u4F5C\u7EE7\u7EED\u9075\u5B88 DSH \u6743\u9650\u4E0E\u5BA1\u6279\u3002";
|
|
756
778
|
function nativeProductionPrompt(production, job, references) {
|
|
@@ -905,7 +927,53 @@ function reorderSequence(sequence, source, target) {
|
|
|
905
927
|
}
|
|
906
928
|
|
|
907
929
|
// src/client/drama-production-view.tsx
|
|
908
|
-
var import_jsx_runtime3 = require("react/jsx-runtime"), SECTION_LABELS = { shots: "\u955C\u5934", assets: "\u7D20\u6750", tasks: "\u4EFB\u52A1", sequence: "\u6210\u7247", canvas: "\u753B\u5E03" }, SECTION_ORDER = Object.keys(SECTION_LABELS), STATUS_LABELS = { awaiting_confirmation: "\u7B49\u5F85\u786E\u8BA4", pending: "\u5DF2\u63D0\u4EA4", running: "DSH \u6267\u884C\u4E2D", dispatched_unknown: "\u5F85\u6838\u5BF9", succeeded: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25", canceled: "\u5DF2\u53D6\u6D88" }, ASSET_KIND_LABEL = { character: "\u4EBA\u7269", scene: "\u573A\u666F", prop: "\u9053\u5177", state: "\u72B6\u6001", unknown: "\u8BBE\u5B9A" }, JOB_KIND_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", composition: "\u6210\u7247" };
|
|
930
|
+
var import_jsx_runtime3 = require("react/jsx-runtime"), SECTION_LABELS = { shots: "\u955C\u5934", assets: "\u7D20\u6750", tasks: "\u4EFB\u52A1", sequence: "\u6210\u7247", canvas: "\u753B\u5E03" }, SECTION_ORDER = Object.keys(SECTION_LABELS), STATUS_LABELS = { awaiting_confirmation: "\u7B49\u5F85\u786E\u8BA4", pending: "\u5DF2\u63D0\u4EA4", running: "DSH \u6267\u884C\u4E2D", dispatched_unknown: "\u5F85\u6838\u5BF9", succeeded: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25", canceled: "\u5DF2\u53D6\u6D88" }, ASSET_KIND_LABEL = { character: "\u4EBA\u7269", scene: "\u573A\u666F", prop: "\u9053\u5177", state: "\u72B6\u6001", unknown: "\u8BBE\u5B9A" }, JOB_KIND_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", composition: "\u6210\u7247" }, MODALITY_LABEL = { image: "\u56FE\u7247", video: "\u89C6\u9891", music: "\u97F3\u4E50" };
|
|
931
|
+
function ProductionEnvironment({ sessionId }) {
|
|
932
|
+
let [preflight, setPreflight] = (0, import_react.useState)(), [attempt, setAttempt] = (0, import_react.useState)(0);
|
|
933
|
+
(0, import_react.useEffect)(() => {
|
|
934
|
+
let controller = new AbortController();
|
|
935
|
+
return fetch(endpoint("drama-preflight", sessionId), { signal: controller.signal }).then(async (response) => {
|
|
936
|
+
if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
|
|
937
|
+
let summary = await response.json();
|
|
938
|
+
controller.signal.aborted || setPreflight(summary);
|
|
939
|
+
}).catch(() => {
|
|
940
|
+
controller.signal.aborted || setPreflight("failed");
|
|
941
|
+
}), () => {
|
|
942
|
+
controller.abort();
|
|
943
|
+
};
|
|
944
|
+
}, [attempt, sessionId]);
|
|
945
|
+
let unconfigured = typeof preflight == "object" ? preflight.adapters.filter((adapter) => !adapter.configured) : [];
|
|
946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-production-environment", role: "status", "aria-label": "\u5A92\u4F53\u751F\u6210\u73AF\u5883", children: [
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "\u751F\u6210\u73AF\u5883" }),
|
|
948
|
+
preflight === void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "data-pending": !0, children: "\u68C0\u67E5\u4E2D\u2026" }),
|
|
949
|
+
preflight === "failed" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: () => {
|
|
950
|
+
setPreflight(void 0), setAttempt((value) => value + 1);
|
|
951
|
+
}, children: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25 \xB7 \u91CD\u8BD5" }),
|
|
952
|
+
typeof preflight == "object" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
953
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "data-ready": preflight.python.ok || void 0, children: [
|
|
954
|
+
"Python ",
|
|
955
|
+
preflight.python.version ?? "\u672A\u627E\u5230"
|
|
956
|
+
] }),
|
|
957
|
+
preflight.adapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "data-ready": adapter.configured || void 0, title: adapter.configured ? `${adapter.name} \u5DF2\u914D\u7F6E` : `\u7F3A\u5C11\u73AF\u5883\u53D8\u91CF ${adapter.missing.join("\u3001")}`, children: [
|
|
958
|
+
MODALITY_LABEL[adapter.modality],
|
|
959
|
+
" ",
|
|
960
|
+
adapter.label,
|
|
961
|
+
adapter.configured ? "" : ` \xB7 \u7F3A ${adapter.missing.join("\u3001")}`
|
|
962
|
+
] }, adapter.name)),
|
|
963
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("em", { children: [
|
|
964
|
+
"DeepSeek \u53EA\u8D1F\u8D23\u5199\u63D0\u793A\u8BCD\uFF1B\u56FE\u7247\u3001\u89C6\u9891\u3001\u97F3\u4E50\u7531\u4E0A\u9762\u7684\u4F9B\u5E94\u5546 API \u751F\u6210\uFF0CKey \u5728\u542F\u52A8 DSH \u524D\u5199\u5165\u5BBF\u4E3B\u673A\u73AF\u5883\u53D8\u91CF\u3002",
|
|
965
|
+
unconfigured.length === preflight.adapters.length && " \u5F53\u524D\u4E00\u4E2A\u90FD\u6CA1\u914D\u7F6E\uFF0C\u751F\u4EA7\u4EFB\u52A1\u4F1A\u505C\u5728 adapter \u4E4B\u524D\u3002",
|
|
966
|
+
" ",
|
|
967
|
+
"Adapter \u914D\u7F6E",
|
|
968
|
+
preflight.adapterConfig.generated ? "\u5DF2\u81EA\u52A8\u767B\u8BB0" : "\u4F7F\u7528\u81EA\u5B9A\u4E49\u6587\u4EF6",
|
|
969
|
+
preflight.adapterConfig.ok ? "" : "\uFF08\u5199\u5165\u5931\u8D25\uFF09",
|
|
970
|
+
"\uFF1A",
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: preflight.adapterConfig.path }),
|
|
972
|
+
"\u3002\u8BE6\u89C1 README\u300C\u5A92\u4F53\u751F\u6210 API\u300D\u3002"
|
|
973
|
+
] })
|
|
974
|
+
] })
|
|
975
|
+
] });
|
|
976
|
+
}
|
|
909
977
|
function handleSectionKey(event, current, onChange) {
|
|
910
978
|
let index = SECTION_ORDER.indexOf(current), next = event.key === "Home" ? 0 : event.key === "End" ? SECTION_ORDER.length - 1 : event.key === "ArrowRight" ? (index + 1) % SECTION_ORDER.length : event.key === "ArrowLeft" ? (index - 1 + SECTION_ORDER.length) % SECTION_ORDER.length : void 0;
|
|
911
979
|
next !== void 0 && (event.preventDefault(), onChange(SECTION_ORDER[next]), event.currentTarget.parentElement?.querySelectorAll("[role='tab']")[next]?.focus());
|
|
@@ -1006,6 +1074,7 @@ ${item.prompt}`).join(`
|
|
|
1006
1074
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: props.onRefresh, children: "\u5237\u65B0" })
|
|
1007
1075
|
] })
|
|
1008
1076
|
] }),
|
|
1077
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ProductionEnvironment, { sessionId: props.sessionId }),
|
|
1009
1078
|
notice !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-production-notice", role: "status", children: [
|
|
1010
1079
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: notice }),
|
|
1011
1080
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => {
|
|
@@ -1083,7 +1152,7 @@ function ShotBoard(props) {
|
|
|
1083
1152
|
] })
|
|
1084
1153
|
] }),
|
|
1085
1154
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-reference-links", children: [
|
|
1086
|
-
shot.source !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReferenceButton, { id: shot.source, production: props.production, onNavigate: props.onNavigate }),
|
|
1155
|
+
shot.sceneIds.length > 0 ? shot.sceneIds.map((sceneId) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReferenceButton, { id: sceneId, production: props.production, onNavigate: props.onNavigate }, sceneId)) : shot.source !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReferenceButton, { id: shot.source, production: props.production, onNavigate: props.onNavigate }),
|
|
1087
1156
|
shot.references.map((id) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReferenceButton, { id, production: props.production, onNavigate: props.onNavigate }, id))
|
|
1088
1157
|
] }),
|
|
1089
1158
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "oh-story-card-actions", children: [
|
|
@@ -1419,21 +1488,6 @@ function settledProductionIntents(chat) {
|
|
|
1419
1488
|
|
|
1420
1489
|
// src/client/video-studio.tsx
|
|
1421
1490
|
var import_react2 = require("react");
|
|
1422
|
-
|
|
1423
|
-
// src/client/workbench-ui.ts
|
|
1424
|
-
function handleTabKey(event, values, current, select) {
|
|
1425
|
-
let index;
|
|
1426
|
-
if (event.key === "Home" ? index = 0 : event.key === "End" ? index = values.length - 1 : event.key === "ArrowRight" ? index = (values.indexOf(current) + 1) % values.length : event.key === "ArrowLeft" && (index = (values.indexOf(current) - 1 + values.length) % values.length), index === void 0) return;
|
|
1427
|
-
event.preventDefault();
|
|
1428
|
-
let value = values[index];
|
|
1429
|
-
value !== void 0 && (select(value), event.currentTarget.parentElement?.querySelectorAll("[role='tab']")[index]?.focus());
|
|
1430
|
-
}
|
|
1431
|
-
function endpoint(path, sessionId, file) {
|
|
1432
|
-
let url = new URL(`/oh-story/${path}`, globalThis.location.origin);
|
|
1433
|
-
return url.searchParams.set("sessionId", sessionId), file !== void 0 && url.searchParams.set("path", file), url.toString();
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
// src/client/video-studio.tsx
|
|
1437
1491
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1438
1492
|
function preferredPreview(project) {
|
|
1439
1493
|
return project.previews.find((item) => item.role === "final") ?? project.previews.find((item) => item.role === "edited") ?? project.previews.find((item) => item.role === "source");
|
|
@@ -1644,7 +1698,8 @@ function VideoStudio({
|
|
|
1644
1698
|
labelledBy,
|
|
1645
1699
|
onProject,
|
|
1646
1700
|
onTab,
|
|
1647
|
-
onWorkbench
|
|
1701
|
+
onWorkbench,
|
|
1702
|
+
onCollapse
|
|
1648
1703
|
}) {
|
|
1649
1704
|
let project = projects.find((item) => item.id === projectId) ?? projects[0], tabsId = (0, import_react2.useId)();
|
|
1650
1705
|
(0, import_react2.useEffect)(() => {
|
|
@@ -1653,23 +1708,26 @@ function VideoStudio({
|
|
|
1653
1708
|
let tabs = ["preview", "artifacts"];
|
|
1654
1709
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("main", { id: paneId, className: "oh-video-studio", role: "tabpanel", "aria-labelledby": labelledBy, hidden, children: [
|
|
1655
1710
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "oh-video-toolbar", children: [
|
|
1656
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.
|
|
1657
|
-
"
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "oh-workbench-cluster", children: [
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "oh-video-mode-tabs", role: "tablist", "aria-label": "\u521B\u4F5C\u5DE5\u4F5C\u53F0", children: workbenches.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1713
|
+
"button",
|
|
1714
|
+
{
|
|
1715
|
+
type: "button",
|
|
1716
|
+
role: "tab",
|
|
1717
|
+
"aria-selected": mode === "video",
|
|
1718
|
+
tabIndex: mode === "video" ? 0 : -1,
|
|
1719
|
+
onKeyDown: (event) => {
|
|
1720
|
+
handleTabKey(event, workbenches, "video", onWorkbench);
|
|
1721
|
+
},
|
|
1722
|
+
onClick: () => {
|
|
1723
|
+
onWorkbench(mode);
|
|
1724
|
+
},
|
|
1725
|
+
children: workbenchLabel(mode)
|
|
1668
1726
|
},
|
|
1669
|
-
|
|
1670
|
-
},
|
|
1671
|
-
|
|
1672
|
-
|
|
1727
|
+
mode
|
|
1728
|
+
)) }),
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "oh-workbench-collapse", type: "button", title: "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", "aria-label": "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", onClick: onCollapse, children: "\xD7" })
|
|
1730
|
+
] }),
|
|
1673
1731
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "oh-video-project", children: [
|
|
1674
1732
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u89C6\u9891\u9879\u76EE" }),
|
|
1675
1733
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("select", { "aria-label": "\u89C6\u9891\u9879\u76EE", value: project?.id ?? "", disabled: project === void 0, onChange: (event) => {
|
|
@@ -1715,14 +1773,94 @@ function VideoStudio({
|
|
|
1715
1773
|
] });
|
|
1716
1774
|
}
|
|
1717
1775
|
|
|
1776
|
+
// src/client/workbench-presence.ts
|
|
1777
|
+
function hasCreativeProject(workspace) {
|
|
1778
|
+
return workspace === void 0 ? !1 : workspace.files.length > 0 || workspace.videos.length > 0 || workspace.games.some((game) => game.source === "workspace");
|
|
1779
|
+
}
|
|
1780
|
+
function resolveWorkbenchOpen(preference, creativeProject) {
|
|
1781
|
+
return preference === void 0 ? creativeProject : preference === "open";
|
|
1782
|
+
}
|
|
1783
|
+
function workbenchPreferenceKey(cwd) {
|
|
1784
|
+
return `oh-story.workbench.${cwd}`;
|
|
1785
|
+
}
|
|
1786
|
+
function readWorkbenchPreference(storage, cwd) {
|
|
1787
|
+
if (storage === void 0 || cwd === void 0) return;
|
|
1788
|
+
let value;
|
|
1789
|
+
try {
|
|
1790
|
+
value = storage.getItem(workbenchPreferenceKey(cwd));
|
|
1791
|
+
} catch {
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
return value === "open" || value === "closed" ? value : void 0;
|
|
1795
|
+
}
|
|
1796
|
+
function writeWorkbenchPreference(storage, cwd, preference) {
|
|
1797
|
+
if (!(storage === void 0 || cwd === void 0))
|
|
1798
|
+
try {
|
|
1799
|
+
storage.setItem(workbenchPreferenceKey(cwd), preference);
|
|
1800
|
+
} catch {
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
function workbenchPreferenceStorage() {
|
|
1804
|
+
try {
|
|
1805
|
+
return globalThis.localStorage;
|
|
1806
|
+
} catch {
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1718
1811
|
// inline-css:/home/runner/work/oh-story-dsh/oh-story-dsh/packages/dsh-plugin/src/client/plugin.css
|
|
1719
1812
|
var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
1813
|
+
.oh-story-welcome {
|
|
1814
|
+
box-sizing: border-box;
|
|
1815
|
+
order: -1;
|
|
1816
|
+
flex-shrink: 0;
|
|
1817
|
+
width: min(640px, calc(100% - 32px));
|
|
1818
|
+
margin: 24px auto;
|
|
1819
|
+
padding: 20px 24px;
|
|
1820
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1821
|
+
border-radius: 12px;
|
|
1822
|
+
color: var(--dsw-alias-label-primary);
|
|
1823
|
+
background: var(--dsw-alias-bg-base);
|
|
1824
|
+
font: 14px/1.7 var(--dsw-font-family);
|
|
1825
|
+
overflow-wrap: anywhere;
|
|
1826
|
+
}
|
|
1827
|
+
.oh-story-welcome h2 { margin: 0 0 8px; font-size: 20px; }
|
|
1828
|
+
.oh-story-welcome p { margin: 8px 0 0; }
|
|
1829
|
+
.oh-story-welcome ol { margin: 12px 0; padding-left: 24px; }
|
|
1720
1830
|
.oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }
|
|
1721
1831
|
|
|
1832
|
+
/* Collapsed, the plugin owns nothing but this control: DSH renders the
|
|
1833
|
+
conversation exactly as it does without the plugin installed. The launcher is
|
|
1834
|
+
fixed to the conversation column's own corner, which the bridge publishes,
|
|
1835
|
+
because the surrounding shell is not ours to place things in. */
|
|
1836
|
+
.oh-story-launcher {
|
|
1837
|
+
box-sizing: border-box;
|
|
1838
|
+
display: flex;
|
|
1839
|
+
position: fixed;
|
|
1840
|
+
z-index: 9;
|
|
1841
|
+
top: calc(var(--oh-story-seam-top, 0px) + 10px);
|
|
1842
|
+
right: calc(var(--oh-story-seam-right, 0px) + 14px);
|
|
1843
|
+
min-height: 28px;
|
|
1844
|
+
align-items: center;
|
|
1845
|
+
gap: 6px;
|
|
1846
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1847
|
+
border-radius: 999px;
|
|
1848
|
+
color: var(--dsw-alias-label-secondary);
|
|
1849
|
+
background: var(--dsw-alias-bg-base);
|
|
1850
|
+
padding: 3px 11px;
|
|
1851
|
+
cursor: pointer;
|
|
1852
|
+
font-family: var(--dsw-font-family);
|
|
1853
|
+
font-size: 12px;
|
|
1854
|
+
line-height: 20px;
|
|
1855
|
+
}
|
|
1856
|
+
.oh-story-launcher b { font-weight: 500; }
|
|
1857
|
+
.oh-story-launcher:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
1858
|
+
.oh-story-launcher:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }
|
|
1859
|
+
|
|
1722
1860
|
/* DSH documents every [data-slot] wrapper as a stable addressable styling
|
|
1723
1861
|
seam. The official Session body and composer stay mounted; this only turns
|
|
1724
1862
|
their scroll host into a three-column writing surface. */
|
|
1725
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
1863
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
1726
1864
|
--os-border: var(--dsw-alias-border-l2);
|
|
1727
1865
|
--os-muted: var(--dsw-alias-label-secondary);
|
|
1728
1866
|
display: grid;
|
|
@@ -1737,7 +1875,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1737
1875
|
}
|
|
1738
1876
|
|
|
1739
1877
|
/* Keep the final Chat flow above the overlapping official Composer. */
|
|
1740
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1878
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1741
1879
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface) {
|
|
1742
1880
|
grid-column: 3;
|
|
1743
1881
|
grid-row: 1;
|
|
@@ -1746,12 +1884,12 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1746
1884
|
border-left: 1px solid var(--os-border);
|
|
1747
1885
|
}
|
|
1748
1886
|
|
|
1749
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1887
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1750
1888
|
[data-chat-flow] {
|
|
1751
1889
|
padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);
|
|
1752
1890
|
}
|
|
1753
1891
|
|
|
1754
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1892
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1755
1893
|
> [data-composer-seat] {
|
|
1756
1894
|
grid-column: 3;
|
|
1757
1895
|
grid-row: 1;
|
|
@@ -1765,7 +1903,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1765
1903
|
|
|
1766
1904
|
/* Game mode keeps the official Conversation on the right but merges the two
|
|
1767
1905
|
creator columns into one playable Studio. */
|
|
1768
|
-
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
1906
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
1769
1907
|
--game-stage: #0d100e;
|
|
1770
1908
|
--game-stage-raised: #161a17;
|
|
1771
1909
|
--game-accent: var(--dsw-alias-state-business-primary);
|
|
@@ -1775,9 +1913,9 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1775
1913
|
overflow: hidden;
|
|
1776
1914
|
}
|
|
1777
1915
|
|
|
1778
|
-
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1916
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1779
1917
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface),
|
|
1780
|
-
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1918
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1781
1919
|
> [data-composer-seat] { grid-column: 2; }
|
|
1782
1920
|
|
|
1783
1921
|
/* DSH 0.1.2 lays two 40px column-resize strips (z-index 8) over the whole
|
|
@@ -2053,6 +2191,27 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2053
2191
|
.oh-story-role button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }
|
|
2054
2192
|
.oh-story-save:disabled { opacity: .48; cursor: default; }
|
|
2055
2193
|
|
|
2194
|
+
.oh-story-brand-actions { display: flex; flex: none; align-items: center; gap: 2px; }
|
|
2195
|
+
|
|
2196
|
+
.oh-workbench-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }
|
|
2197
|
+
.oh-workbench-collapse {
|
|
2198
|
+
display: grid;
|
|
2199
|
+
width: 28px;
|
|
2200
|
+
height: 28px;
|
|
2201
|
+
flex: none;
|
|
2202
|
+
place-items: center;
|
|
2203
|
+
border: 0;
|
|
2204
|
+
border-radius: 5px;
|
|
2205
|
+
color: var(--os-muted);
|
|
2206
|
+
background: transparent;
|
|
2207
|
+
padding: 0;
|
|
2208
|
+
cursor: pointer;
|
|
2209
|
+
font: inherit;
|
|
2210
|
+
font-size: 16px;
|
|
2211
|
+
}
|
|
2212
|
+
.oh-workbench-collapse:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
2213
|
+
.oh-workbench-collapse:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }
|
|
2214
|
+
|
|
2056
2215
|
.oh-story-mode-tabs { display: flex; margin: 0 4px 8px; padding: 2px; border: 1px solid var(--os-border); border-radius: 7px; background: var(--dsw-alias-bg-layer-1); }
|
|
2057
2216
|
|
|
2058
2217
|
.oh-story-mode-tabs button,
|
|
@@ -2313,6 +2472,16 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2313
2472
|
.oh-story-production-summary { color: var(--os-muted); white-space: nowrap; }
|
|
2314
2473
|
.oh-story-production-notice { justify-content: space-between; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-bg-layer-1); }
|
|
2315
2474
|
.oh-story-production-notice button { border: 0; background: transparent; }
|
|
2475
|
+
.oh-story-production-environment { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 5px 10px; margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--os-border); border-radius: 7px; color: var(--os-muted); background: var(--dsw-alias-bg-layer-1); font-size: 10px; }
|
|
2476
|
+
/* Environment names such as MINIMAX_VIDEO_RESOLUTIONS and the temp-dir path are longer than the 500 px editor column; let them break rather than widen the view. */
|
|
2477
|
+
.oh-story-production-environment > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
|
|
2478
|
+
.oh-story-production-environment strong { color: var(--dsw-alias-label-secondary); font-size: 11px; }
|
|
2479
|
+
.oh-story-production-environment span::before { content: "\u25CF"; margin-right: 4px; color: var(--video-danger, #d9534f); }
|
|
2480
|
+
.oh-story-production-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }
|
|
2481
|
+
.oh-story-production-environment span[data-pending]::before { color: var(--os-muted); }
|
|
2482
|
+
.oh-story-production-environment em { flex-basis: 100%; font-style: normal; line-height: 1.5; }
|
|
2483
|
+
.oh-story-production-environment code { font-size: 10px; overflow-wrap: anywhere; }
|
|
2484
|
+
.oh-story-production-environment button { min-height: 24px; border: 1px solid var(--os-border); border-radius: 6px; padding: 0 8px; color: inherit; background: var(--dsw-alias-bg-base); cursor: pointer; font: inherit; }
|
|
2316
2485
|
.oh-story-production-diagnostics { margin: 8px 12px 0; padding: 7px 9px; border: 1px solid var(--dsw-alias-state-warn-label); border-radius: 7px; background: var(--dsw-specific-tip); }
|
|
2317
2486
|
.oh-story-production-diagnostics summary { color: var(--dsw-alias-state-warn-label); cursor: pointer; }
|
|
2318
2487
|
.oh-story-production-diagnostics ul { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; list-style: none; }
|
|
@@ -2436,11 +2605,11 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2436
2605
|
.oh-story-canvas article span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2437
2606
|
.oh-story-canvas article span { color: var(--os-muted); font-size: 10px; }
|
|
2438
2607
|
|
|
2439
|
-
[data-conversation-scroll][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2608
|
+
[data-conversation-scroll][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2440
2609
|
grid-template-columns: clamp(104px, 18%, 184px) minmax(200px, 1fr) clamp(300px, 45%, 408px);
|
|
2441
2610
|
}
|
|
2442
2611
|
|
|
2443
|
-
[data-conversation-scroll][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2612
|
+
[data-conversation-scroll][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2444
2613
|
grid-template-columns: clamp(80px, 16%, 104px) minmax(0, 1fr) clamp(228px, 48%, 300px);
|
|
2445
2614
|
}
|
|
2446
2615
|
|
|
@@ -2483,12 +2652,12 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2483
2652
|
[data-oh-story-layout="compact"] .oh-story-jsonl summary > code,
|
|
2484
2653
|
[data-oh-story-layout="compact"] .oh-story-jsonl summary > em { display: none; }
|
|
2485
2654
|
|
|
2486
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2655
|
+
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2487
2656
|
grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px);
|
|
2488
2657
|
}
|
|
2489
2658
|
[data-oh-story-workbench="game"][data-oh-story-layout="medium"] .oh-game-toolbar { grid-template-columns: auto minmax(140px, 1fr) auto; }
|
|
2490
2659
|
|
|
2491
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2660
|
+
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2492
2661
|
display: grid;
|
|
2493
2662
|
grid-template-columns: minmax(0, 1fr);
|
|
2494
2663
|
overflow: hidden;
|
|
@@ -2523,7 +2692,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2523
2692
|
gap: 5px;
|
|
2524
2693
|
padding: 4px 8px;
|
|
2525
2694
|
}
|
|
2526
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-
|
|
2695
|
+
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-toolbar > .oh-workbench-cluster { grid-column: 1; grid-row: 1; width: fit-content; }
|
|
2527
2696
|
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-project > span { display: none; }
|
|
2528
2697
|
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-project { grid-column: 1 / -1; grid-row: 2; }
|
|
2529
2698
|
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-project select { max-width: none; width: 100%; min-height: 44px; }
|
|
@@ -2549,7 +2718,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2549
2718
|
align-content: center;
|
|
2550
2719
|
padding: 4px 8px;
|
|
2551
2720
|
}
|
|
2552
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-studio[data-oh-game-narrow] .oh-game-
|
|
2721
|
+
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-studio[data-oh-game-narrow] .oh-game-toolbar > .oh-workbench-cluster {
|
|
2553
2722
|
grid-column: 1;
|
|
2554
2723
|
grid-row: 2;
|
|
2555
2724
|
justify-self: start;
|
|
@@ -2607,7 +2776,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2607
2776
|
|
|
2608
2777
|
/* Video mode intentionally stays a preview surface: one player, a read-only artifact view,
|
|
2609
2778
|
and the official DSH Conversation. It shares no nonlinear-editor or timeline runtime. */
|
|
2610
|
-
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2779
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2611
2780
|
--video-stage: #0b0d10;
|
|
2612
2781
|
--video-stage-raised: #15181d;
|
|
2613
2782
|
--video-accent: var(--dsw-alias-state-business-primary);
|
|
@@ -2616,9 +2785,9 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2616
2785
|
grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);
|
|
2617
2786
|
overflow: hidden;
|
|
2618
2787
|
}
|
|
2619
|
-
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
2788
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
2620
2789
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface),
|
|
2621
|
-
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
2790
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
2622
2791
|
> [data-composer-seat] { grid-column: 2; }
|
|
2623
2792
|
|
|
2624
2793
|
.oh-video-studio {
|
|
@@ -2762,10 +2931,10 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2762
2931
|
.oh-video-artifact-content { min-width: 0; min-height: 0; flex: 1; overflow: auto; }
|
|
2763
2932
|
.oh-video-artifact-content pre { min-width: 0; min-height: 100%; box-sizing: border-box; margin: 0; padding: 20px; color: inherit; background: var(--dsw-alias-bg-base); white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.65 var(--dsw-font-family-mono, ui-monospace, monospace); }
|
|
2764
2933
|
|
|
2765
|
-
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) { grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px); }
|
|
2934
|
+
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) { grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px); }
|
|
2766
2935
|
[data-oh-story-workbench="video"][data-oh-story-layout="medium"] .oh-video-project select { width: 100%; }
|
|
2767
2936
|
|
|
2768
|
-
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) { display: grid; grid-template-columns: minmax(0, 1fr); overflow: hidden; }
|
|
2937
|
+
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) { display: grid; grid-template-columns: minmax(0, 1fr); overflow: hidden; }
|
|
2769
2938
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]
|
|
2770
2939
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface),
|
|
2771
2940
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]
|
|
@@ -2778,7 +2947,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2778
2947
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"][data-oh-studio-pane="chat"] .oh-video-studio { display: none; }
|
|
2779
2948
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-game-mobile-switcher { display: flex; position: absolute; top: 8px; right: 8px; z-index: 20; border-color: var(--dsw-alias-border-l1); box-shadow: 0 4px 14px rgb(0 0 0 / 12%); }
|
|
2780
2949
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-toolbar { min-height: 142px; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 44px 44px 38px; align-content: center; gap: 2px 6px; padding: 4px 8px; }
|
|
2781
|
-
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-
|
|
2950
|
+
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-toolbar > .oh-workbench-cluster { grid-column: 1 / -1; grid-row: 1; width: fit-content; }
|
|
2782
2951
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-tabs { grid-column: 2; grid-row: 2; justify-self: end; }
|
|
2783
2952
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-project { grid-column: 1; grid-row: 2; }
|
|
2784
2953
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-project > span { display: none; }
|
|
@@ -2801,6 +2970,7 @@ function createWorkbenchStore() {
|
|
|
2801
2970
|
return (0, import_dsh_client_store.defineStore)({
|
|
2802
2971
|
init: () => ({
|
|
2803
2972
|
buffers: {},
|
|
2973
|
+
workbenchPreference: void 0,
|
|
2804
2974
|
editorMode: "preview",
|
|
2805
2975
|
expanded: {},
|
|
2806
2976
|
selected: void 0,
|
|
@@ -2825,6 +2995,9 @@ function createWorkbenchStore() {
|
|
|
2825
2995
|
setBuffers: (draft, update) => {
|
|
2826
2996
|
draft.buffers = applyUpdate(draft.buffers, update);
|
|
2827
2997
|
},
|
|
2998
|
+
setWorkbenchPreference: (draft, update) => {
|
|
2999
|
+
draft.workbenchPreference = applyUpdate(draft.workbenchPreference, update);
|
|
3000
|
+
},
|
|
2828
3001
|
setEditorMode: (draft, update) => {
|
|
2829
3002
|
draft.editorMode = applyUpdate(draft.editorMode, update);
|
|
2830
3003
|
},
|
|
@@ -3126,6 +3299,7 @@ function GameStudio({
|
|
|
3126
3299
|
paneId,
|
|
3127
3300
|
labelledBy,
|
|
3128
3301
|
onWorkbench,
|
|
3302
|
+
onCollapse,
|
|
3129
3303
|
onSelect
|
|
3130
3304
|
}) {
|
|
3131
3305
|
let project = workspace.games.find((value) => value.id === gameProjectId) ?? workspace.games[0], studioRef = (0, import_react3.useRef)(null), tabsId = (0, import_react3.useId)();
|
|
@@ -3146,23 +3320,26 @@ function GameStudio({
|
|
|
3146
3320
|
let tabs = ["preview", "design"];
|
|
3147
3321
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("main", { ref: studioRef, id: paneId, className: "oh-game-studio", "data-source": project.source, role: "tabpanel", "aria-labelledby": labelledBy, hidden, children: [
|
|
3148
3322
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "oh-game-toolbar", children: [
|
|
3149
|
-
|
|
3150
|
-
"
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3323
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "oh-workbench-cluster", children: [
|
|
3324
|
+
workbenches.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "oh-game-mode-tabs", role: "tablist", "aria-label": "\u521B\u4F5C\u5DE5\u4F5C\u53F0", children: workbenches.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3325
|
+
"button",
|
|
3326
|
+
{
|
|
3327
|
+
type: "button",
|
|
3328
|
+
role: "tab",
|
|
3329
|
+
"aria-selected": mode === "game",
|
|
3330
|
+
tabIndex: mode === "game" ? 0 : -1,
|
|
3331
|
+
onKeyDown: (event) => {
|
|
3332
|
+
handleTabKey(event, workbenches, "game", onWorkbench);
|
|
3333
|
+
},
|
|
3334
|
+
onClick: () => {
|
|
3335
|
+
onWorkbench(mode);
|
|
3336
|
+
},
|
|
3337
|
+
children: workbenchLabel(mode)
|
|
3161
3338
|
},
|
|
3162
|
-
|
|
3163
|
-
},
|
|
3164
|
-
|
|
3165
|
-
|
|
3339
|
+
mode
|
|
3340
|
+
)) }),
|
|
3341
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "oh-workbench-collapse", type: "button", title: "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", "aria-label": "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", onClick: onCollapse, children: "\xD7" })
|
|
3342
|
+
] }),
|
|
3166
3343
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "oh-game-project", title: "\u5207\u6362\u9879\u76EE\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9", children: [
|
|
3167
3344
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u6E38\u620F\u9879\u76EE" }),
|
|
3168
3345
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u6E38\u620F\u9879\u76EE\uFF1B\u5207\u6362\u5C06\u91CD\u65B0\u8F7D\u5165\u8BD5\u73A9", value: project.id, onChange: (event) => {
|
|
@@ -3209,16 +3386,24 @@ function CreativeWorkbench({
|
|
|
3209
3386
|
sendProductionPrompt,
|
|
3210
3387
|
cancelProduction,
|
|
3211
3388
|
removeQueuedProduction,
|
|
3389
|
+
workspace,
|
|
3390
|
+
error,
|
|
3391
|
+
workspaceLoading,
|
|
3392
|
+
reload,
|
|
3393
|
+
open,
|
|
3394
|
+
creativeProject,
|
|
3212
3395
|
useStore,
|
|
3213
3396
|
actions
|
|
3214
3397
|
}) {
|
|
3215
|
-
let
|
|
3398
|
+
let activities = (0, import_react3.useMemo)(
|
|
3216
3399
|
() => fileMutations(runningCalls, partial),
|
|
3217
3400
|
[partial, runningCalls]
|
|
3218
3401
|
), normalizedActivities = (0, import_react3.useMemo)(() => activities.flatMap((activity2) => {
|
|
3219
3402
|
let path = creativeRelativePath(activity2.path, workspace?.cwd);
|
|
3220
3403
|
return path === void 0 ? [] : [{ activity: activity2, path }];
|
|
3221
|
-
}), [activities, workspace?.cwd]), primaryActivity = normalizedActivities.at(-1), activityPaths = (0, import_react3.useMemo)(() => new Set(normalizedActivities.map((value) => value.path)), [normalizedActivities]), activity = primaryActivity?.activity, activityPath = primaryActivity?.path, workbench = useStore((memory) => memory.workbench), setWorkbench = actions.setWorkbench, gameTab = useStore((memory) => memory.gameTab), setGameTab = actions.setGameTab, gameProjectId = useStore((memory) => memory.gameProjectId), setGameProjectId = actions.setGameProjectId, gamePane = useStore((memory) => memory.gamePane), setGamePane = actions.setGamePane, videoTab = useStore((memory) => memory.videoTab), setVideoTab = actions.setVideoTab, videoProjectId = useStore((memory) => memory.videoProjectId), setVideoProjectId = actions.setVideoProjectId, videoPane = useStore((memory) => memory.videoPane), setVideoPane = actions.setVideoPane, selected = useStore((memory) => memory.selected), setSelected = actions.setSelected, buffers = useStore((memory) => memory.buffers), setBuffers = actions.setBuffers, buffersRef = (0, import_react3.useRef)({}), expanded = useStore((memory) => memory.expanded), setExpanded = actions.setExpanded, productionSection = useStore((memory) => memory.productionSection), setProductionSection = actions.setProductionSection, productionSelectedIds = useStore((memory) => memory.productionSelectedIds), productionJobsByEpisode = useStore((memory) => memory.productionJobs), productionSelectionsByEpisode = useStore((memory) => memory.productionSelections), productionReferencesByEpisode = useStore((memory) => memory.productionReferences), productionSequenceByEpisode = useStore((memory) => memory.productionSequence), productionCanvasByEpisode = useStore((memory) => memory.productionCanvas), productionZoomByEpisode = useStore((memory) => memory.productionZoom), productionIntentCalls = useStore((memory) => memory.productionIntentCalls), surfaceRef = (0, import_react3.useRef)(null),
|
|
3404
|
+
}), [activities, workspace?.cwd]), primaryActivity = normalizedActivities.at(-1), activityPaths = (0, import_react3.useMemo)(() => new Set(normalizedActivities.map((value) => value.path)), [normalizedActivities]), activity = primaryActivity?.activity, activityPath = primaryActivity?.path, workbench = useStore((memory) => memory.workbench), setWorkbench = actions.setWorkbench, gameTab = useStore((memory) => memory.gameTab), setGameTab = actions.setGameTab, gameProjectId = useStore((memory) => memory.gameProjectId), setGameProjectId = actions.setGameProjectId, gamePane = useStore((memory) => memory.gamePane), setGamePane = actions.setGamePane, videoTab = useStore((memory) => memory.videoTab), setVideoTab = actions.setVideoTab, videoProjectId = useStore((memory) => memory.videoProjectId), setVideoProjectId = actions.setVideoProjectId, videoPane = useStore((memory) => memory.videoPane), setVideoPane = actions.setVideoPane, selected = useStore((memory) => memory.selected), setSelected = actions.setSelected, buffers = useStore((memory) => memory.buffers), setBuffers = actions.setBuffers, buffersRef = (0, import_react3.useRef)({}), expanded = useStore((memory) => memory.expanded), setExpanded = actions.setExpanded, productionSection = useStore((memory) => memory.productionSection), setProductionSection = actions.setProductionSection, productionSelectedIds = useStore((memory) => memory.productionSelectedIds), productionJobsByEpisode = useStore((memory) => memory.productionJobs), productionSelectionsByEpisode = useStore((memory) => memory.productionSelections), productionReferencesByEpisode = useStore((memory) => memory.productionReferences), productionSequenceByEpisode = useStore((memory) => memory.productionSequence), productionCanvasByEpisode = useStore((memory) => memory.productionCanvas), productionZoomByEpisode = useStore((memory) => memory.productionZoom), productionIntentCalls = useStore((memory) => memory.productionIntentCalls), surfaceRef = (0, import_react3.useRef)(null), setWorkbenchPreference = actions.setWorkbenchPreference, applyWorkbenchPreference = (0, import_react3.useCallback)((preference) => {
|
|
3405
|
+
setWorkbenchPreference(preference), writeWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd, preference);
|
|
3406
|
+
}, [setWorkbenchPreference, workspace?.cwd]), compactTabsId = (0, import_react3.useId)(), compactStudioId = `${compactTabsId}-studio-panel`, compactVideoStudioId = `${compactTabsId}-video-studio-panel`, compactChatId = `${compactTabsId}-chat-panel`, navRef = (0, import_react3.useRef)(null), activityBases = (0, import_react3.useRef)(/* @__PURE__ */ new Map()), previousSignals = (0, import_react3.useRef)(/* @__PURE__ */ new Set()), previousSettledMutation = (0, import_react3.useRef)(settledMutation), saveLocks = (0, import_react3.useRef)(/* @__PURE__ */ new Set()), buffer = selected === void 0 ? void 0 : buffers[selected], selectedFile = workspace?.files.find((file) => file.path === selected), selectedMedia = selectedFile?.kind === "media", dirty = buffer?.source === "human" && buffer.content !== buffer.saved, saving = buffer?.saving === !0, fileError = buffer?.error, conflict = buffer?.conflict, selectedLower = selected?.toLocaleLowerCase(), markdown = selectedLower?.endsWith(".md") === !0, jsonl = selectedLower?.endsWith(".jsonl") === !0, structured = jsonl || selectedLower?.endsWith(".json") === !0, previewable = markdown || jsonl, episodeDirectory = episodeDirectoryForPath(selected), productionAvailable = selected !== void 0 && isCreatorDocumentPath(selected) && episodeDirectory !== void 0, editorModes = productionAvailable ? EDITOR_MODES : EDITOR_MODES.filter((mode) => mode !== "production"), episodeDocumentPaths = (0, import_react3.useMemo)(
|
|
3222
3407
|
() => episodeDirectory === void 0 ? [] : creatorDocumentPaths(workspace?.files.filter((file) => file.kind === "text") ?? [], episodeDirectory),
|
|
3223
3408
|
[episodeDirectory, workspace?.files]
|
|
3224
3409
|
), episodeDocuments = (0, import_react3.useMemo)(() => Object.fromEntries(episodeDocumentPaths.flatMap((path) => {
|
|
@@ -3506,7 +3691,7 @@ function CreativeWorkbench({
|
|
|
3506
3691
|
}
|
|
3507
3692
|
}
|
|
3508
3693
|
}, [selected]), (0, import_react3.useEffect)(() => {
|
|
3509
|
-
if (normalizedActivities.length > 0 || workspace === void 0) return;
|
|
3694
|
+
if (!open || normalizedActivities.length > 0 || workspace === void 0) return;
|
|
3510
3695
|
let sessionSurface = surfaceRef.current?.parentElement;
|
|
3511
3696
|
if (sessionSurface == null) return;
|
|
3512
3697
|
let knownPaths = new Set(workspace.files.map((file) => file.path)), followOfficialFileLink = (event) => {
|
|
@@ -3526,7 +3711,7 @@ function CreativeWorkbench({
|
|
|
3526
3711
|
return sessionSurface.addEventListener("click", followOfficialFileLink, !0), () => {
|
|
3527
3712
|
sessionSurface.removeEventListener("click", followOfficialFileLink, !0);
|
|
3528
3713
|
};
|
|
3529
|
-
}, [normalizedActivities.length, revealPath, workspace]), (0, import_react3.useEffect)(() => {
|
|
3714
|
+
}, [normalizedActivities.length, open, revealPath, workspace]), (0, import_react3.useEffect)(() => {
|
|
3530
3715
|
if (workbench !== "game" && workbench !== "video") return;
|
|
3531
3716
|
let surface = surfaceRef.current, sessionSurface = surface?.parentElement, chat = Array.from(sessionSurface?.children ?? []).find((child) => child !== surface && child instanceof HTMLElement);
|
|
3532
3717
|
if (!(chat instanceof HTMLElement)) return;
|
|
@@ -3610,13 +3795,14 @@ function CreativeWorkbench({
|
|
|
3610
3795
|
}
|
|
3611
3796
|
}, [reload, sessionId]);
|
|
3612
3797
|
(0, import_react3.useEffect)(() => {
|
|
3798
|
+
if (!open) return;
|
|
3613
3799
|
let saveShortcut = (event) => {
|
|
3614
3800
|
!(event.metaKey || event.ctrlKey) || event.key.toLocaleLowerCase() !== "s" || (event.preventDefault(), selected !== void 0 && savePath(selected));
|
|
3615
3801
|
};
|
|
3616
3802
|
return globalThis.addEventListener("keydown", saveShortcut), () => {
|
|
3617
3803
|
globalThis.removeEventListener("keydown", saveShortcut);
|
|
3618
3804
|
};
|
|
3619
|
-
}, [savePath, selected]);
|
|
3805
|
+
}, [open, savePath, selected]);
|
|
3620
3806
|
let groups = (0, import_react3.useMemo)(() => {
|
|
3621
3807
|
let value = /* @__PURE__ */ new Map(), all = [...workspace?.files ?? []].filter((file) => workbenchModeForPath(file.path) === workbench);
|
|
3622
3808
|
activityPath !== void 0 && !all.some((file) => file.path === activityPath) && all.push({ path: activityPath, bytes: 0, version: "", kind: "text" }), all.sort((left, right) => left.path.localeCompare(right.path, "zh-Hans-CN"));
|
|
@@ -3641,8 +3827,8 @@ function CreativeWorkbench({
|
|
|
3641
3827
|
}, navigateProductionTarget = (target) => {
|
|
3642
3828
|
let before = (buffersRef.current[target.path]?.content ?? "").slice(0, target.offset), approximateScrollTop = Math.max(0, before.split(/\r?\n/u).length * 28 - 96);
|
|
3643
3829
|
editorPositions.current.set(target.path, { scrollTop: approximateScrollTop, selectionStart: target.offset, selectionEnd: target.offset }), modeSelection.current = target.path, revealPath(target.path), setEditorMode("source");
|
|
3644
|
-
}, selectedLabel = selected ?? `\u5728\u5F53\u524D DSH workspace \u4E2D\u9009\u62E9${workbenchLabel(workbench)}\u6587\u4EF6`, selectedBasename = selected?.split("/").at(-1) ?? selectedLabel, selectedGroup = selected === void 0 ? void 0 : groupForPath(selected), toggleGroup = (key,
|
|
3645
|
-
setExpanded((current) => ({ ...current, [key]:
|
|
3830
|
+
}, selectedLabel = selected ?? `\u5728\u5F53\u524D DSH workspace \u4E2D\u9009\u62E9${workbenchLabel(workbench)}\u6587\u4EF6`, selectedBasename = selected?.split("/").at(-1) ?? selectedLabel, selectedGroup = selected === void 0 ? void 0 : groupForPath(selected), toggleGroup = (key, open2) => {
|
|
3831
|
+
setExpanded((current) => ({ ...current, [key]: open2 }));
|
|
3646
3832
|
}, resolveConflict = (keepLocal) => {
|
|
3647
3833
|
if (selected === void 0 || conflict?.theirs === void 0 || conflict.theirsVersion === void 0) return;
|
|
3648
3834
|
let theirs = conflict.theirs, theirsVersion = conflict.theirsVersion;
|
|
@@ -3654,7 +3840,7 @@ function CreativeWorkbench({
|
|
|
3654
3840
|
};
|
|
3655
3841
|
});
|
|
3656
3842
|
};
|
|
3657
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-workbench": workbench, children: [
|
|
3843
|
+
return open ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "true", "data-workbench": workbench, children: [
|
|
3658
3844
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
|
|
3659
3845
|
(workbench === "game" || workbench === "video") && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "oh-game-mobile-switcher", role: "tablist", "aria-label": workbench === "game" ? "\u7A84\u5C4F\u6E38\u620F\u5DE5\u4F5C\u53F0" : "\u7A84\u5C4F\u89C6\u9891\u5DE5\u4F5C\u53F0", children: ["studio", "chat"].map((pane) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3660
3846
|
"button",
|
|
@@ -3692,6 +3878,9 @@ function CreativeWorkbench({
|
|
|
3692
3878
|
paneId: compactStudioId,
|
|
3693
3879
|
labelledBy: `${compactTabsId}-studio-tab`,
|
|
3694
3880
|
onWorkbench: selectWorkbench,
|
|
3881
|
+
onCollapse: () => {
|
|
3882
|
+
applyWorkbenchPreference("closed");
|
|
3883
|
+
},
|
|
3695
3884
|
onSelect: revealPath
|
|
3696
3885
|
}
|
|
3697
3886
|
),
|
|
@@ -3710,7 +3899,10 @@ function CreativeWorkbench({
|
|
|
3710
3899
|
labelledBy: `${compactTabsId}-studio-tab`,
|
|
3711
3900
|
onProject: setVideoProjectId,
|
|
3712
3901
|
onTab: setVideoTab,
|
|
3713
|
-
onWorkbench: selectWorkbench
|
|
3902
|
+
onWorkbench: selectWorkbench,
|
|
3903
|
+
onCollapse: () => {
|
|
3904
|
+
applyWorkbenchPreference("closed");
|
|
3905
|
+
}
|
|
3714
3906
|
}
|
|
3715
3907
|
),
|
|
3716
3908
|
workbench !== "game" && workbench !== "video" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -3723,7 +3915,12 @@ function CreativeWorkbench({
|
|
|
3723
3915
|
] }),
|
|
3724
3916
|
workspaceKind !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "oh-story-kind", children: workspaceKind === "story" ? "\u5C0F\u8BF4" : "\u77ED\u5267" })
|
|
3725
3917
|
] }),
|
|
3726
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
3918
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "oh-story-brand-actions", children: [
|
|
3919
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: reload, title: "\u5237\u65B0", "aria-label": "\u5237\u65B0\u9879\u76EE\u6587\u4EF6", children: "\u21BB" }),
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: () => {
|
|
3921
|
+
applyWorkbenchPreference("closed");
|
|
3922
|
+
}, title: "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", "aria-label": "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", children: "\xD7" })
|
|
3923
|
+
] })
|
|
3727
3924
|
] }),
|
|
3728
3925
|
workspace !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "oh-story-mode-tabs", role: "tablist", "aria-label": "\u521B\u4F5C\u5DE5\u4F5C\u53F0", children: WORKBENCH_MODES.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3729
3926
|
"button",
|
|
@@ -3836,6 +4033,7 @@ function CreativeWorkbench({
|
|
|
3836
4033
|
] }) : editorMode === "production" && productionAvailable && episodeProduction !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3837
4034
|
DramaProductionView,
|
|
3838
4035
|
{
|
|
4036
|
+
sessionId,
|
|
3839
4037
|
production: episodeProduction,
|
|
3840
4038
|
sessionRunning,
|
|
3841
4039
|
queue: productionQueue,
|
|
@@ -3895,10 +4093,21 @@ function CreativeWorkbench({
|
|
|
3895
4093
|
)
|
|
3896
4094
|
] })
|
|
3897
4095
|
] })
|
|
4096
|
+
] }) : !creativeProject && error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "false", children: [
|
|
4097
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
|
|
4098
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "oh-story-launcher", type: "button", title: error ?? "\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0", "aria-label": "\u6253\u5F00\u521B\u4F5C\u5DE5\u4F5C\u53F0", onClick: () => {
|
|
4099
|
+
applyWorkbenchPreference("open");
|
|
4100
|
+
}, children: [
|
|
4101
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": !0, children: "\u2726" }),
|
|
4102
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: "\u521B\u4F5C\u5DE5\u4F5C\u53F0" })
|
|
4103
|
+
] })
|
|
3898
4104
|
] });
|
|
3899
4105
|
}
|
|
3900
4106
|
function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions, sendProductionPrompt, cancelProduction, removeQueuedProduction }) {
|
|
3901
|
-
let marker = (0, import_react3.useRef)(null), [target, setTarget] = (0, import_react3.useState)(), runningCalls = useChat((snapshot) => snapshot.legacy.runningCalls), partial = useChat((snapshot) => streamingAssistant(snapshot.timeline)), settledMutation = useChat((snapshot) => latestSettledMutation(snapshot)), workbench = useStore((memory) => memory.workbench), gamePane = useStore((memory) => memory.gamePane), videoPane = useStore((memory) => memory.videoPane), sessionRunning = useSession((snapshot) => snapshot.running), productionQueue = useSession((snapshot) => snapshot.queue.map((item) => ({ id: item.id, preview: item.preview }))), chat = useChat((snapshot) => snapshot), productionIntents = (0, import_react3.useMemo)(() => settledProductionIntents(chat), [chat])
|
|
4107
|
+
let marker = (0, import_react3.useRef)(null), [target, setTarget] = (0, import_react3.useState)(), runningCalls = useChat((snapshot) => snapshot.legacy.runningCalls), partial = useChat((snapshot) => streamingAssistant(snapshot.timeline)), settledMutation = useChat((snapshot) => latestSettledMutation(snapshot)), workbench = useStore((memory) => memory.workbench), gamePane = useStore((memory) => memory.gamePane), videoPane = useStore((memory) => memory.videoPane), sessionRunning = useSession((snapshot) => snapshot.running), productionQueue = useSession((snapshot) => snapshot.queue.map((item) => ({ id: item.id, preview: item.preview }))), chat = useChat((snapshot) => snapshot), productionIntents = (0, import_react3.useMemo)(() => settledProductionIntents(chat), [chat]), { workspace, error, loading: workspaceLoading, reload } = useWorkspace(sessionId), chosenPreference = useStore((memory) => memory.workbenchPreference), creativeProject = hasCreativeProject(workspace), storedPreference = (0, import_react3.useMemo)(
|
|
4108
|
+
() => readWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd),
|
|
4109
|
+
[workspace?.cwd]
|
|
4110
|
+
), open = resolveWorkbenchOpen(chosenPreference ?? storedPreference, creativeProject);
|
|
3902
4111
|
return (0, import_react3.useLayoutEffect)(() => {
|
|
3903
4112
|
let document = marker.current?.ownerDocument;
|
|
3904
4113
|
if (document === void 0) return;
|
|
@@ -3914,8 +4123,21 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3914
4123
|
}, [sessionId]), (0, import_react3.useLayoutEffect)(() => {
|
|
3915
4124
|
let scroller = target?.parentElement;
|
|
3916
4125
|
if (scroller == null) return;
|
|
4126
|
+
if (!open) {
|
|
4127
|
+
let publishSeam = () => {
|
|
4128
|
+
let box = scroller.getBoundingClientRect();
|
|
4129
|
+
scroller.style.setProperty("--oh-story-seam-top", `${String(box.top)}px`), scroller.style.setProperty("--oh-story-seam-right", `${String(scroller.ownerDocument.documentElement.clientWidth - box.right)}px`);
|
|
4130
|
+
};
|
|
4131
|
+
publishSeam();
|
|
4132
|
+
let seams = new ResizeObserver(publishSeam);
|
|
4133
|
+
seams.observe(scroller);
|
|
4134
|
+
let view = scroller.ownerDocument.defaultView;
|
|
4135
|
+
return view?.addEventListener("resize", publishSeam), () => {
|
|
4136
|
+
seams.disconnect(), view?.removeEventListener("resize", publishSeam), scroller.style.removeProperty("--oh-story-seam-top"), scroller.style.removeProperty("--oh-story-seam-right");
|
|
4137
|
+
};
|
|
4138
|
+
}
|
|
3917
4139
|
let composerSeat = () => scroller.querySelector(":scope > [data-composer-seat]"), parkedAtTail = () => scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight <= 8, parked = parkedAtTail(), drivenAt = 0, markDriven = (event) => {
|
|
3918
|
-
event.target instanceof Node && composerSeat()?.contains(event.target) === !0 || (drivenAt = performance.now());
|
|
4140
|
+
event.target instanceof Node && composerSeat()?.contains(event.target) === !0 || event.type === "pointerdown" && event.target !== scroller || (drivenAt = performance.now());
|
|
3919
4141
|
}, trackParked = () => {
|
|
3920
4142
|
parkedAtTail() ? parked = !0 : performance.now() - drivenAt < 400 && (parked = !1);
|
|
3921
4143
|
}, publishLayout = () => {
|
|
@@ -3947,7 +4169,7 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3947
4169
|
scroller.removeEventListener(driven, markDriven);
|
|
3948
4170
|
observer.disconnect(), seats.disconnect(), scroller.style.removeProperty("--oh-story-scroll-height"), scroller.style.removeProperty("--oh-story-composer-height"), delete scroller.dataset.ohStoryLayout, delete scroller.dataset.ohStoryWorkbench, delete scroller.dataset.ohStudioPane;
|
|
3949
4171
|
};
|
|
3950
|
-
}, [gamePane, target, videoPane, workbench]), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
4172
|
+
}, [gamePane, open, target, videoPane, workbench]), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3951
4173
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { ref: marker, className: "oh-story-bridge-marker", "aria-hidden": !0 }),
|
|
3952
4174
|
target === void 0 ? null : (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3953
4175
|
CreativeWorkbench,
|
|
@@ -3959,6 +4181,12 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3959
4181
|
sessionRunning,
|
|
3960
4182
|
productionQueue,
|
|
3961
4183
|
productionIntents,
|
|
4184
|
+
workspace,
|
|
4185
|
+
error,
|
|
4186
|
+
workspaceLoading,
|
|
4187
|
+
reload,
|
|
4188
|
+
open,
|
|
4189
|
+
creativeProject,
|
|
3962
4190
|
sendProductionPrompt,
|
|
3963
4191
|
cancelProduction,
|
|
3964
4192
|
removeQueuedProduction,
|
|
@@ -3968,8 +4196,47 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3968
4196
|
), target)
|
|
3969
4197
|
] });
|
|
3970
4198
|
}
|
|
4199
|
+
function WorkbenchWelcome() {
|
|
4200
|
+
let marker = (0, import_react3.useRef)(null), [target, setTarget] = (0, import_react3.useState)();
|
|
4201
|
+
return (0, import_react3.useLayoutEffect)(() => {
|
|
4202
|
+
let document = marker.current?.ownerDocument;
|
|
4203
|
+
if (document === void 0) return;
|
|
4204
|
+
let locate = () => {
|
|
4205
|
+
let anchor = document.querySelector("[data-conversation-scroll]");
|
|
4206
|
+
setTarget((current) => current === anchor ? current : anchor ?? void 0);
|
|
4207
|
+
};
|
|
4208
|
+
locate();
|
|
4209
|
+
let observer = new MutationObserver(locate);
|
|
4210
|
+
return observer.observe(document.body, { childList: !0, subtree: !0 }), () => {
|
|
4211
|
+
observer.disconnect();
|
|
4212
|
+
};
|
|
4213
|
+
}, []), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
|
|
4215
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { ref: marker, className: "oh-story-bridge-marker", "aria-hidden": !0 }),
|
|
4216
|
+
target === void 0 ? null : (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "oh-story-welcome", "aria-label": "Oh Story \u4F7F\u7528\u5F15\u5BFC", children: [
|
|
4217
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: "Oh Story \u5DF2\u52A0\u8F7D" }),
|
|
4218
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u4F5C\u54C1\u76EE\u5F55\u4E2D\u6709\u521B\u4F5C\u6587\u4EF6\u65F6\uFF0C\u5C0F\u8BF4\u3001\u77ED\u5267\u3001\u6E38\u620F\u3001\u89C6\u9891\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u663E\u793A\u3002" }),
|
|
4219
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("ol", { children: [
|
|
4220
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u70B9\u51FB\u5DE6\u4FA7\u300C\u6DFB\u52A0\u5DE5\u4F5C\u533A / Add workspace\u300D\u7684 \uFF0B\uFF0C\u9009\u62E9\u5B58\u653E\u4F5C\u54C1\u7684\u6587\u4EF6\u5939\u3002" }),
|
|
4221
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u5728\u4E0B\u65B9\u300C\u9009\u62E9\u5DE5\u4F5C\u533A / Choose workspace\u300D\u4E2D\u9009\u4E2D\u8BE5\u76EE\u5F55\uFF0C\u6216\u6253\u5F00\u5DF2\u6709\u4F1A\u8BDD\u3002" }),
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: "\u7A7A\u76EE\u5F55\u5148\u5728 Chat \u4E2D\u5F00\u59CB\u521B\u4F5C\uFF0C\u751F\u6210\u7B2C\u4E00\u4E2A\u521B\u4F5C\u6587\u4EF6\u540E\uFF0C\u5DE5\u4F5C\u53F0\u4F1A\u81EA\u52A8\u51FA\u73B0\u3002" })
|
|
4223
|
+
] }),
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
4225
|
+
"\u67E5\u770B\u5DF2\u6709\u4F5C\u54C1\u65E0\u9700 API Key\u3002\u5F00\u59CB AI \u521B\u4F5C\u524D\uFF0C\u5728\u300C\u8BBE\u7F6E \u2192 \u6A21\u578B\u300D\u914D\u7F6E\u6A21\u578B\uFF0C\u518D\u8F93\u5165 ",
|
|
4226
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/story" }),
|
|
4227
|
+
"\u3001",
|
|
4228
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/short-drama" }),
|
|
4229
|
+
"\u3001",
|
|
4230
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/novel-to-game quick" }),
|
|
4231
|
+
" \u6216 ",
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: "/video-recap" }),
|
|
4233
|
+
"\u3002"
|
|
4234
|
+
] })
|
|
4235
|
+
] }), target)
|
|
4236
|
+
] });
|
|
4237
|
+
}
|
|
3971
4238
|
function WorkbenchSeat({ SessionProvider, renderSlot }) {
|
|
3972
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SessionProvider, { children: renderSlot("oh-story.workspace", {}) });
|
|
4239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SessionProvider, { empty: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WorkbenchWelcome, {}), children: renderSlot("oh-story.workspace", {}) });
|
|
3973
4240
|
}
|
|
3974
4241
|
function argsOf(block) {
|
|
3975
4242
|
let raw = ("kind" in block ? block.call?.argsRaw : block.argsRaw) ?? "{}";
|