@oh-story/dsh 0.1.6 → 0.1.7
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 +10 -8
- package/lib/client.js +298 -87
- 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,77 @@ 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; }
|
|
1720
1813
|
.oh-story-split-surface { display: contents; font-family: var(--dsw-font-family); }
|
|
1721
1814
|
|
|
1815
|
+
/* Collapsed, the plugin owns nothing but this control: DSH renders the
|
|
1816
|
+
conversation exactly as it does without the plugin installed. The launcher is
|
|
1817
|
+
fixed to the conversation column's own corner, which the bridge publishes,
|
|
1818
|
+
because the surrounding shell is not ours to place things in. */
|
|
1819
|
+
.oh-story-launcher {
|
|
1820
|
+
box-sizing: border-box;
|
|
1821
|
+
display: flex;
|
|
1822
|
+
position: fixed;
|
|
1823
|
+
z-index: 9;
|
|
1824
|
+
top: calc(var(--oh-story-seam-top, 0px) + 10px);
|
|
1825
|
+
right: calc(var(--oh-story-seam-right, 0px) + 14px);
|
|
1826
|
+
min-height: 28px;
|
|
1827
|
+
align-items: center;
|
|
1828
|
+
gap: 6px;
|
|
1829
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1830
|
+
border-radius: 999px;
|
|
1831
|
+
color: var(--dsw-alias-label-secondary);
|
|
1832
|
+
background: var(--dsw-alias-bg-base);
|
|
1833
|
+
padding: 3px 11px;
|
|
1834
|
+
cursor: pointer;
|
|
1835
|
+
font-family: var(--dsw-font-family);
|
|
1836
|
+
font-size: 12px;
|
|
1837
|
+
line-height: 20px;
|
|
1838
|
+
}
|
|
1839
|
+
.oh-story-launcher b { font-weight: 500; }
|
|
1840
|
+
.oh-story-launcher:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
1841
|
+
.oh-story-launcher:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 2px; }
|
|
1842
|
+
|
|
1722
1843
|
/* DSH documents every [data-slot] wrapper as a stable addressable styling
|
|
1723
1844
|
seam. The official Session body and composer stay mounted; this only turns
|
|
1724
1845
|
their scroll host into a three-column writing surface. */
|
|
1725
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
1846
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
1726
1847
|
--os-border: var(--dsw-alias-border-l2);
|
|
1727
1848
|
--os-muted: var(--dsw-alias-label-secondary);
|
|
1728
1849
|
display: grid;
|
|
@@ -1737,7 +1858,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1737
1858
|
}
|
|
1738
1859
|
|
|
1739
1860
|
/* Keep the final Chat flow above the overlapping official Composer. */
|
|
1740
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1861
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1741
1862
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface) {
|
|
1742
1863
|
grid-column: 3;
|
|
1743
1864
|
grid-row: 1;
|
|
@@ -1746,12 +1867,12 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1746
1867
|
border-left: 1px solid var(--os-border);
|
|
1747
1868
|
}
|
|
1748
1869
|
|
|
1749
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1870
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1750
1871
|
[data-chat-flow] {
|
|
1751
1872
|
padding-bottom: calc(max(var(--dsh-composer-height, 152px), var(--oh-story-composer-height, 0px)) + 16px);
|
|
1752
1873
|
}
|
|
1753
1874
|
|
|
1754
|
-
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1875
|
+
[data-conversation-scroll]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1755
1876
|
> [data-composer-seat] {
|
|
1756
1877
|
grid-column: 3;
|
|
1757
1878
|
grid-row: 1;
|
|
@@ -1765,7 +1886,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1765
1886
|
|
|
1766
1887
|
/* Game mode keeps the official Conversation on the right but merges the two
|
|
1767
1888
|
creator columns into one playable Studio. */
|
|
1768
|
-
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
1889
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
1769
1890
|
--game-stage: #0d100e;
|
|
1770
1891
|
--game-stage-raised: #161a17;
|
|
1771
1892
|
--game-accent: var(--dsw-alias-state-business-primary);
|
|
@@ -1775,9 +1896,9 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
1775
1896
|
overflow: hidden;
|
|
1776
1897
|
}
|
|
1777
1898
|
|
|
1778
|
-
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
1899
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1779
1900
|
> [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)
|
|
1901
|
+
[data-conversation-scroll][data-oh-story-workbench="game"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
1781
1902
|
> [data-composer-seat] { grid-column: 2; }
|
|
1782
1903
|
|
|
1783
1904
|
/* DSH 0.1.2 lays two 40px column-resize strips (z-index 8) over the whole
|
|
@@ -2053,6 +2174,27 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2053
2174
|
.oh-story-role button:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }
|
|
2054
2175
|
.oh-story-save:disabled { opacity: .48; cursor: default; }
|
|
2055
2176
|
|
|
2177
|
+
.oh-story-brand-actions { display: flex; flex: none; align-items: center; gap: 2px; }
|
|
2178
|
+
|
|
2179
|
+
.oh-workbench-cluster { display: flex; min-width: 0; align-items: center; gap: 6px; }
|
|
2180
|
+
.oh-workbench-collapse {
|
|
2181
|
+
display: grid;
|
|
2182
|
+
width: 28px;
|
|
2183
|
+
height: 28px;
|
|
2184
|
+
flex: none;
|
|
2185
|
+
place-items: center;
|
|
2186
|
+
border: 0;
|
|
2187
|
+
border-radius: 5px;
|
|
2188
|
+
color: var(--os-muted);
|
|
2189
|
+
background: transparent;
|
|
2190
|
+
padding: 0;
|
|
2191
|
+
cursor: pointer;
|
|
2192
|
+
font: inherit;
|
|
2193
|
+
font-size: 16px;
|
|
2194
|
+
}
|
|
2195
|
+
.oh-workbench-collapse:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
2196
|
+
.oh-workbench-collapse:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }
|
|
2197
|
+
|
|
2056
2198
|
.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
2199
|
|
|
2058
2200
|
.oh-story-mode-tabs button,
|
|
@@ -2313,6 +2455,16 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2313
2455
|
.oh-story-production-summary { color: var(--os-muted); white-space: nowrap; }
|
|
2314
2456
|
.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
2457
|
.oh-story-production-notice button { border: 0; background: transparent; }
|
|
2458
|
+
.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; }
|
|
2459
|
+
/* 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. */
|
|
2460
|
+
.oh-story-production-environment > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
|
|
2461
|
+
.oh-story-production-environment strong { color: var(--dsw-alias-label-secondary); font-size: 11px; }
|
|
2462
|
+
.oh-story-production-environment span::before { content: "\u25CF"; margin-right: 4px; color: var(--video-danger, #d9534f); }
|
|
2463
|
+
.oh-story-production-environment span[data-ready]::before { color: var(--dsw-alias-state-success-primary, #45b96f); }
|
|
2464
|
+
.oh-story-production-environment span[data-pending]::before { color: var(--os-muted); }
|
|
2465
|
+
.oh-story-production-environment em { flex-basis: 100%; font-style: normal; line-height: 1.5; }
|
|
2466
|
+
.oh-story-production-environment code { font-size: 10px; overflow-wrap: anywhere; }
|
|
2467
|
+
.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
2468
|
.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
2469
|
.oh-story-production-diagnostics summary { color: var(--dsw-alias-state-warn-label); cursor: pointer; }
|
|
2318
2470
|
.oh-story-production-diagnostics ul { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; list-style: none; }
|
|
@@ -2436,11 +2588,11 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2436
2588
|
.oh-story-canvas article span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2437
2589
|
.oh-story-canvas article span { color: var(--os-muted); font-size: 10px; }
|
|
2438
2590
|
|
|
2439
|
-
[data-conversation-scroll][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2591
|
+
[data-conversation-scroll][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2440
2592
|
grid-template-columns: clamp(104px, 18%, 184px) minmax(200px, 1fr) clamp(300px, 45%, 408px);
|
|
2441
2593
|
}
|
|
2442
2594
|
|
|
2443
|
-
[data-conversation-scroll][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2595
|
+
[data-conversation-scroll][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2444
2596
|
grid-template-columns: clamp(80px, 16%, 104px) minmax(0, 1fr) clamp(228px, 48%, 300px);
|
|
2445
2597
|
}
|
|
2446
2598
|
|
|
@@ -2483,12 +2635,12 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2483
2635
|
[data-oh-story-layout="compact"] .oh-story-jsonl summary > code,
|
|
2484
2636
|
[data-oh-story-layout="compact"] .oh-story-jsonl summary > em { display: none; }
|
|
2485
2637
|
|
|
2486
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="medium"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2638
|
+
[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
2639
|
grid-template-columns: minmax(0, 1fr) clamp(360px, 42%, 440px);
|
|
2488
2640
|
}
|
|
2489
2641
|
[data-oh-story-workbench="game"][data-oh-story-layout="medium"] .oh-game-toolbar { grid-template-columns: auto minmax(140px, 1fr) auto; }
|
|
2490
2642
|
|
|
2491
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface) {
|
|
2643
|
+
[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
2644
|
display: grid;
|
|
2493
2645
|
grid-template-columns: minmax(0, 1fr);
|
|
2494
2646
|
overflow: hidden;
|
|
@@ -2523,7 +2675,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2523
2675
|
gap: 5px;
|
|
2524
2676
|
padding: 4px 8px;
|
|
2525
2677
|
}
|
|
2526
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-
|
|
2678
|
+
[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
2679
|
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-project > span { display: none; }
|
|
2528
2680
|
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-project { grid-column: 1 / -1; grid-row: 2; }
|
|
2529
2681
|
[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 +2701,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2549
2701
|
align-content: center;
|
|
2550
2702
|
padding: 4px 8px;
|
|
2551
2703
|
}
|
|
2552
|
-
[data-conversation-scroll][data-oh-story-workbench="game"][data-oh-story-layout="compact"] .oh-game-studio[data-oh-game-narrow] .oh-game-
|
|
2704
|
+
[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
2705
|
grid-column: 1;
|
|
2554
2706
|
grid-row: 2;
|
|
2555
2707
|
justify-self: start;
|
|
@@ -2607,7 +2759,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2607
2759
|
|
|
2608
2760
|
/* Video mode intentionally stays a preview surface: one player, a read-only artifact view,
|
|
2609
2761
|
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) {
|
|
2762
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"]) {
|
|
2611
2763
|
--video-stage: #0b0d10;
|
|
2612
2764
|
--video-stage-raised: #15181d;
|
|
2613
2765
|
--video-accent: var(--dsw-alias-state-business-primary);
|
|
@@ -2616,9 +2768,9 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2616
2768
|
grid-template-columns: minmax(0, 1fr) clamp(400px, 34%, 520px);
|
|
2617
2769
|
overflow: hidden;
|
|
2618
2770
|
}
|
|
2619
|
-
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface)
|
|
2771
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
2620
2772
|
> [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)
|
|
2773
|
+
[data-conversation-scroll][data-oh-story-workbench="video"]:has(> [data-slot="conversation.session"] > .oh-story-split-surface[data-open="true"])
|
|
2622
2774
|
> [data-composer-seat] { grid-column: 2; }
|
|
2623
2775
|
|
|
2624
2776
|
.oh-video-studio {
|
|
@@ -2762,10 +2914,10 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2762
2914
|
.oh-video-artifact-content { min-width: 0; min-height: 0; flex: 1; overflow: auto; }
|
|
2763
2915
|
.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
2916
|
|
|
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); }
|
|
2917
|
+
[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
2918
|
[data-oh-story-workbench="video"][data-oh-story-layout="medium"] .oh-video-project select { width: 100%; }
|
|
2767
2919
|
|
|
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; }
|
|
2920
|
+
[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
2921
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]
|
|
2770
2922
|
> [data-slot="conversation.session"] > :not(.oh-story-split-surface),
|
|
2771
2923
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"]
|
|
@@ -2778,7 +2930,7 @@ var plugin_default = `.oh-story-bridge-marker { display: none; }
|
|
|
2778
2930
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"][data-oh-studio-pane="chat"] .oh-video-studio { display: none; }
|
|
2779
2931
|
[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
2932
|
[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-
|
|
2933
|
+
[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
2934
|
[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
2935
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-project { grid-column: 1; grid-row: 2; }
|
|
2784
2936
|
[data-conversation-scroll][data-oh-story-workbench="video"][data-oh-story-layout="compact"] .oh-video-project > span { display: none; }
|
|
@@ -2801,6 +2953,7 @@ function createWorkbenchStore() {
|
|
|
2801
2953
|
return (0, import_dsh_client_store.defineStore)({
|
|
2802
2954
|
init: () => ({
|
|
2803
2955
|
buffers: {},
|
|
2956
|
+
workbenchPreference: void 0,
|
|
2804
2957
|
editorMode: "preview",
|
|
2805
2958
|
expanded: {},
|
|
2806
2959
|
selected: void 0,
|
|
@@ -2825,6 +2978,9 @@ function createWorkbenchStore() {
|
|
|
2825
2978
|
setBuffers: (draft, update) => {
|
|
2826
2979
|
draft.buffers = applyUpdate(draft.buffers, update);
|
|
2827
2980
|
},
|
|
2981
|
+
setWorkbenchPreference: (draft, update) => {
|
|
2982
|
+
draft.workbenchPreference = applyUpdate(draft.workbenchPreference, update);
|
|
2983
|
+
},
|
|
2828
2984
|
setEditorMode: (draft, update) => {
|
|
2829
2985
|
draft.editorMode = applyUpdate(draft.editorMode, update);
|
|
2830
2986
|
},
|
|
@@ -3126,6 +3282,7 @@ function GameStudio({
|
|
|
3126
3282
|
paneId,
|
|
3127
3283
|
labelledBy,
|
|
3128
3284
|
onWorkbench,
|
|
3285
|
+
onCollapse,
|
|
3129
3286
|
onSelect
|
|
3130
3287
|
}) {
|
|
3131
3288
|
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 +3303,26 @@ function GameStudio({
|
|
|
3146
3303
|
let tabs = ["preview", "design"];
|
|
3147
3304
|
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
3305
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "oh-game-toolbar", children: [
|
|
3149
|
-
|
|
3150
|
-
"
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "oh-workbench-cluster", children: [
|
|
3307
|
+
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)(
|
|
3308
|
+
"button",
|
|
3309
|
+
{
|
|
3310
|
+
type: "button",
|
|
3311
|
+
role: "tab",
|
|
3312
|
+
"aria-selected": mode === "game",
|
|
3313
|
+
tabIndex: mode === "game" ? 0 : -1,
|
|
3314
|
+
onKeyDown: (event) => {
|
|
3315
|
+
handleTabKey(event, workbenches, "game", onWorkbench);
|
|
3316
|
+
},
|
|
3317
|
+
onClick: () => {
|
|
3318
|
+
onWorkbench(mode);
|
|
3319
|
+
},
|
|
3320
|
+
children: workbenchLabel(mode)
|
|
3161
3321
|
},
|
|
3162
|
-
|
|
3163
|
-
},
|
|
3164
|
-
|
|
3165
|
-
|
|
3322
|
+
mode
|
|
3323
|
+
)) }),
|
|
3324
|
+
/* @__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" })
|
|
3325
|
+
] }),
|
|
3166
3326
|
/* @__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
3327
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u6E38\u620F\u9879\u76EE" }),
|
|
3168
3328
|
/* @__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 +3369,24 @@ function CreativeWorkbench({
|
|
|
3209
3369
|
sendProductionPrompt,
|
|
3210
3370
|
cancelProduction,
|
|
3211
3371
|
removeQueuedProduction,
|
|
3372
|
+
workspace,
|
|
3373
|
+
error,
|
|
3374
|
+
workspaceLoading,
|
|
3375
|
+
reload,
|
|
3376
|
+
open,
|
|
3377
|
+
creativeProject,
|
|
3212
3378
|
useStore,
|
|
3213
3379
|
actions
|
|
3214
3380
|
}) {
|
|
3215
|
-
let
|
|
3381
|
+
let activities = (0, import_react3.useMemo)(
|
|
3216
3382
|
() => fileMutations(runningCalls, partial),
|
|
3217
3383
|
[partial, runningCalls]
|
|
3218
3384
|
), normalizedActivities = (0, import_react3.useMemo)(() => activities.flatMap((activity2) => {
|
|
3219
3385
|
let path = creativeRelativePath(activity2.path, workspace?.cwd);
|
|
3220
3386
|
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),
|
|
3387
|
+
}), [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) => {
|
|
3388
|
+
setWorkbenchPreference(preference), writeWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd, preference);
|
|
3389
|
+
}, [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
3390
|
() => episodeDirectory === void 0 ? [] : creatorDocumentPaths(workspace?.files.filter((file) => file.kind === "text") ?? [], episodeDirectory),
|
|
3223
3391
|
[episodeDirectory, workspace?.files]
|
|
3224
3392
|
), episodeDocuments = (0, import_react3.useMemo)(() => Object.fromEntries(episodeDocumentPaths.flatMap((path) => {
|
|
@@ -3506,7 +3674,7 @@ function CreativeWorkbench({
|
|
|
3506
3674
|
}
|
|
3507
3675
|
}
|
|
3508
3676
|
}, [selected]), (0, import_react3.useEffect)(() => {
|
|
3509
|
-
if (normalizedActivities.length > 0 || workspace === void 0) return;
|
|
3677
|
+
if (!open || normalizedActivities.length > 0 || workspace === void 0) return;
|
|
3510
3678
|
let sessionSurface = surfaceRef.current?.parentElement;
|
|
3511
3679
|
if (sessionSurface == null) return;
|
|
3512
3680
|
let knownPaths = new Set(workspace.files.map((file) => file.path)), followOfficialFileLink = (event) => {
|
|
@@ -3526,7 +3694,7 @@ function CreativeWorkbench({
|
|
|
3526
3694
|
return sessionSurface.addEventListener("click", followOfficialFileLink, !0), () => {
|
|
3527
3695
|
sessionSurface.removeEventListener("click", followOfficialFileLink, !0);
|
|
3528
3696
|
};
|
|
3529
|
-
}, [normalizedActivities.length, revealPath, workspace]), (0, import_react3.useEffect)(() => {
|
|
3697
|
+
}, [normalizedActivities.length, open, revealPath, workspace]), (0, import_react3.useEffect)(() => {
|
|
3530
3698
|
if (workbench !== "game" && workbench !== "video") return;
|
|
3531
3699
|
let surface = surfaceRef.current, sessionSurface = surface?.parentElement, chat = Array.from(sessionSurface?.children ?? []).find((child) => child !== surface && child instanceof HTMLElement);
|
|
3532
3700
|
if (!(chat instanceof HTMLElement)) return;
|
|
@@ -3610,13 +3778,14 @@ function CreativeWorkbench({
|
|
|
3610
3778
|
}
|
|
3611
3779
|
}, [reload, sessionId]);
|
|
3612
3780
|
(0, import_react3.useEffect)(() => {
|
|
3781
|
+
if (!open) return;
|
|
3613
3782
|
let saveShortcut = (event) => {
|
|
3614
3783
|
!(event.metaKey || event.ctrlKey) || event.key.toLocaleLowerCase() !== "s" || (event.preventDefault(), selected !== void 0 && savePath(selected));
|
|
3615
3784
|
};
|
|
3616
3785
|
return globalThis.addEventListener("keydown", saveShortcut), () => {
|
|
3617
3786
|
globalThis.removeEventListener("keydown", saveShortcut);
|
|
3618
3787
|
};
|
|
3619
|
-
}, [savePath, selected]);
|
|
3788
|
+
}, [open, savePath, selected]);
|
|
3620
3789
|
let groups = (0, import_react3.useMemo)(() => {
|
|
3621
3790
|
let value = /* @__PURE__ */ new Map(), all = [...workspace?.files ?? []].filter((file) => workbenchModeForPath(file.path) === workbench);
|
|
3622
3791
|
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 +3810,8 @@ function CreativeWorkbench({
|
|
|
3641
3810
|
}, navigateProductionTarget = (target) => {
|
|
3642
3811
|
let before = (buffersRef.current[target.path]?.content ?? "").slice(0, target.offset), approximateScrollTop = Math.max(0, before.split(/\r?\n/u).length * 28 - 96);
|
|
3643
3812
|
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]:
|
|
3813
|
+
}, 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) => {
|
|
3814
|
+
setExpanded((current) => ({ ...current, [key]: open2 }));
|
|
3646
3815
|
}, resolveConflict = (keepLocal) => {
|
|
3647
3816
|
if (selected === void 0 || conflict?.theirs === void 0 || conflict.theirsVersion === void 0) return;
|
|
3648
3817
|
let theirs = conflict.theirs, theirsVersion = conflict.theirsVersion;
|
|
@@ -3654,7 +3823,7 @@ function CreativeWorkbench({
|
|
|
3654
3823
|
};
|
|
3655
3824
|
});
|
|
3656
3825
|
};
|
|
3657
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-workbench": workbench, children: [
|
|
3826
|
+
return open ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "true", "data-workbench": workbench, children: [
|
|
3658
3827
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
|
|
3659
3828
|
(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
3829
|
"button",
|
|
@@ -3692,6 +3861,9 @@ function CreativeWorkbench({
|
|
|
3692
3861
|
paneId: compactStudioId,
|
|
3693
3862
|
labelledBy: `${compactTabsId}-studio-tab`,
|
|
3694
3863
|
onWorkbench: selectWorkbench,
|
|
3864
|
+
onCollapse: () => {
|
|
3865
|
+
applyWorkbenchPreference("closed");
|
|
3866
|
+
},
|
|
3695
3867
|
onSelect: revealPath
|
|
3696
3868
|
}
|
|
3697
3869
|
),
|
|
@@ -3710,7 +3882,10 @@ function CreativeWorkbench({
|
|
|
3710
3882
|
labelledBy: `${compactTabsId}-studio-tab`,
|
|
3711
3883
|
onProject: setVideoProjectId,
|
|
3712
3884
|
onTab: setVideoTab,
|
|
3713
|
-
onWorkbench: selectWorkbench
|
|
3885
|
+
onWorkbench: selectWorkbench,
|
|
3886
|
+
onCollapse: () => {
|
|
3887
|
+
applyWorkbenchPreference("closed");
|
|
3888
|
+
}
|
|
3714
3889
|
}
|
|
3715
3890
|
),
|
|
3716
3891
|
workbench !== "game" && workbench !== "video" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -3723,7 +3898,12 @@ function CreativeWorkbench({
|
|
|
3723
3898
|
] }),
|
|
3724
3899
|
workspaceKind !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "oh-story-kind", children: workspaceKind === "story" ? "\u5C0F\u8BF4" : "\u77ED\u5267" })
|
|
3725
3900
|
] }),
|
|
3726
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
3901
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "oh-story-brand-actions", children: [
|
|
3902
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: reload, title: "\u5237\u65B0", "aria-label": "\u5237\u65B0\u9879\u76EE\u6587\u4EF6", children: "\u21BB" }),
|
|
3903
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: () => {
|
|
3904
|
+
applyWorkbenchPreference("closed");
|
|
3905
|
+
}, title: "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", "aria-label": "\u6536\u8D77\u521B\u4F5C\u5DE5\u4F5C\u53F0", children: "\xD7" })
|
|
3906
|
+
] })
|
|
3727
3907
|
] }),
|
|
3728
3908
|
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
3909
|
"button",
|
|
@@ -3836,6 +4016,7 @@ function CreativeWorkbench({
|
|
|
3836
4016
|
] }) : editorMode === "production" && productionAvailable && episodeProduction !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3837
4017
|
DramaProductionView,
|
|
3838
4018
|
{
|
|
4019
|
+
sessionId,
|
|
3839
4020
|
production: episodeProduction,
|
|
3840
4021
|
sessionRunning,
|
|
3841
4022
|
queue: productionQueue,
|
|
@@ -3895,10 +4076,21 @@ function CreativeWorkbench({
|
|
|
3895
4076
|
)
|
|
3896
4077
|
] })
|
|
3897
4078
|
] })
|
|
4079
|
+
] }) : !creativeProject && error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: surfaceRef, className: "oh-story-split-surface", "data-open": "false", children: [
|
|
4080
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: plugin_default }),
|
|
4081
|
+
/* @__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: () => {
|
|
4082
|
+
applyWorkbenchPreference("open");
|
|
4083
|
+
}, children: [
|
|
4084
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": !0, children: "\u2726" }),
|
|
4085
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: "\u521B\u4F5C\u5DE5\u4F5C\u53F0" })
|
|
4086
|
+
] })
|
|
3898
4087
|
] });
|
|
3899
4088
|
}
|
|
3900
4089
|
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])
|
|
4090
|
+
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)(
|
|
4091
|
+
() => readWorkbenchPreference(workbenchPreferenceStorage(), workspace?.cwd),
|
|
4092
|
+
[workspace?.cwd]
|
|
4093
|
+
), open = resolveWorkbenchOpen(chosenPreference ?? storedPreference, creativeProject);
|
|
3902
4094
|
return (0, import_react3.useLayoutEffect)(() => {
|
|
3903
4095
|
let document = marker.current?.ownerDocument;
|
|
3904
4096
|
if (document === void 0) return;
|
|
@@ -3914,6 +4106,19 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3914
4106
|
}, [sessionId]), (0, import_react3.useLayoutEffect)(() => {
|
|
3915
4107
|
let scroller = target?.parentElement;
|
|
3916
4108
|
if (scroller == null) return;
|
|
4109
|
+
if (!open) {
|
|
4110
|
+
let publishSeam = () => {
|
|
4111
|
+
let box = scroller.getBoundingClientRect();
|
|
4112
|
+
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`);
|
|
4113
|
+
};
|
|
4114
|
+
publishSeam();
|
|
4115
|
+
let seams = new ResizeObserver(publishSeam);
|
|
4116
|
+
seams.observe(scroller);
|
|
4117
|
+
let view = scroller.ownerDocument.defaultView;
|
|
4118
|
+
return view?.addEventListener("resize", publishSeam), () => {
|
|
4119
|
+
seams.disconnect(), view?.removeEventListener("resize", publishSeam), scroller.style.removeProperty("--oh-story-seam-top"), scroller.style.removeProperty("--oh-story-seam-right");
|
|
4120
|
+
};
|
|
4121
|
+
}
|
|
3917
4122
|
let composerSeat = () => scroller.querySelector(":scope > [data-composer-seat]"), parkedAtTail = () => scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight <= 8, parked = parkedAtTail(), drivenAt = 0, markDriven = (event) => {
|
|
3918
4123
|
event.target instanceof Node && composerSeat()?.contains(event.target) === !0 || (drivenAt = performance.now());
|
|
3919
4124
|
}, trackParked = () => {
|
|
@@ -3947,7 +4152,7 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3947
4152
|
scroller.removeEventListener(driven, markDriven);
|
|
3948
4153
|
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
4154
|
};
|
|
3950
|
-
}, [gamePane, target, videoPane, workbench]), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
4155
|
+
}, [gamePane, open, target, videoPane, workbench]), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3951
4156
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { ref: marker, className: "oh-story-bridge-marker", "aria-hidden": !0 }),
|
|
3952
4157
|
target === void 0 ? null : (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3953
4158
|
CreativeWorkbench,
|
|
@@ -3959,6 +4164,12 @@ function CreativeSplitBridge({ sessionId, useSession, useChat, useStore, actions
|
|
|
3959
4164
|
sessionRunning,
|
|
3960
4165
|
productionQueue,
|
|
3961
4166
|
productionIntents,
|
|
4167
|
+
workspace,
|
|
4168
|
+
error,
|
|
4169
|
+
workspaceLoading,
|
|
4170
|
+
reload,
|
|
4171
|
+
open,
|
|
4172
|
+
creativeProject,
|
|
3962
4173
|
sendProductionPrompt,
|
|
3963
4174
|
cancelProduction,
|
|
3964
4175
|
removeQueuedProduction,
|