@agimon-ai/doompi-author 0.0.1-alpha.11 → 0.0.1-alpha.14
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/dist/extensions/web.mjs +185 -98
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/src/types/authorPreview.d.cts +45 -0
- package/dist/src/types/authorPreview.d.cts.map +1 -0
- package/dist/src/types/authorPreview.d.mts +45 -0
- package/dist/src/types/authorPreview.d.mts.map +1 -0
- package/package.json +8 -7
- package/src/types/authorPreview.ts +56 -0
package/dist/extensions/web.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { apiResponse, createApiClient, defineApiRoutes, defineChannelFile, defineDockFace, defineFileLinks, defineGlobalStore, defineLeaderBinding, defineMinorModeFile, defineSessionStore, defineToolRenderer, defineWebLifecycle, defineWebPlugin, sessionApiAddress, toolResultTextLines } from "@agimon-ai/doompi-core/web";
|
|
1
|
+
import { apiResponse, createApiClient, defineApiRoutes, defineChannelFile, defineDockFace, defineFileLinks, defineGlobalStore, defineLeaderBinding, defineMinorModeFile, defineSessionStore, defineSlotFile, defineToolRenderer, defineWebLifecycle, defineWebPlugin, sessionApiAddress, toolResultTextLines } from "@agimon-ai/doompi-core/web";
|
|
2
2
|
import { Store } from "@tanstack/store";
|
|
3
3
|
import { Button, CodeEditor, Markdown, MediaPreview, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, MessageLines, collapseLines, toolTone } from "@agimon-ai/doompi-web-components";
|
|
4
4
|
import { useStore } from "@tanstack/react-store";
|
|
@@ -501,7 +501,7 @@ function putAuthorDocument(sessionId, input) {
|
|
|
501
501
|
},
|
|
502
502
|
regions: [],
|
|
503
503
|
candidate: void 0,
|
|
504
|
-
requests: session.requests.map((request) => request.documentPath === path && (request.status === "REQUESTED" || request.status === "CHANGING" || request.status === "CHANGED") ? {
|
|
504
|
+
requests: session.requests.map((request) => input.kind !== "story-preview" && request.documentPath === path && (request.status === "REQUESTED" || request.status === "CHANGING" || request.status === "CHANGED") ? {
|
|
505
505
|
...request,
|
|
506
506
|
status: "FAILED",
|
|
507
507
|
currentOperation: void 0,
|
|
@@ -1033,6 +1033,7 @@ function utf8Prefix(value, limit) {
|
|
|
1033
1033
|
}
|
|
1034
1034
|
function createAuthorCapturePacket(captureId, capturedAt, document, regions) {
|
|
1035
1035
|
if (regions.length === 0 || regions.length > 16) throw new Error("Capture requires between 1 and 16 regions.");
|
|
1036
|
+
if (document.kind === "story-preview" && document.storyPreview === void 0) throw new Error("Story preview capture requires source provenance.");
|
|
1036
1037
|
const packet = {
|
|
1037
1038
|
version: 1,
|
|
1038
1039
|
captureId,
|
|
@@ -1041,7 +1042,8 @@ function createAuthorCapturePacket(captureId, capturedAt, document, regions) {
|
|
|
1041
1042
|
path: document.path,
|
|
1042
1043
|
kind: document.kind,
|
|
1043
1044
|
revision: document.version,
|
|
1044
|
-
...document.sourceSha256 === void 0 ? {} : { sourceSha256: document.sourceSha256 }
|
|
1045
|
+
...document.sourceSha256 === void 0 ? {} : { sourceSha256: document.sourceSha256 },
|
|
1046
|
+
...document.storyPreview === void 0 ? {} : { storyPreview: structuredClone(document.storyPreview) }
|
|
1045
1047
|
},
|
|
1046
1048
|
regions: regions.map((region, index) => {
|
|
1047
1049
|
if (region.documentPath !== document.path || region.revision !== document.version || region.sourceSha256 !== document.sourceSha256) throw new Error(`Region ${String(index + 1)} is stale for the focused document.`);
|
|
@@ -1073,12 +1075,30 @@ function anchorLocation(anchor) {
|
|
|
1073
1075
|
case "image-rect": return `image ${rectLocation(anchor.rect)}`;
|
|
1074
1076
|
case "pdf-page-rect": return `page ${String(anchor.page)}, ${rectLocation(anchor.rect)}`;
|
|
1075
1077
|
case "video-time-rect": return `time ${anchor.timeSeconds.toFixed(3)}s${anchor.frame === void 0 ? "" : `, frame ${String(anchor.frame)}`}, ${rectLocation(anchor.rect)}`;
|
|
1078
|
+
case "story-preview-rect": return `story preview ${rectLocation(anchor.rect)}`;
|
|
1076
1079
|
}
|
|
1077
1080
|
}
|
|
1081
|
+
function storyPreviewProvenance(packet) {
|
|
1082
|
+
const preview = packet.document.storyPreview;
|
|
1083
|
+
if (preview === void 0) return void 0;
|
|
1084
|
+
const sources = preview.sources.map((source) => `- ${source.path} (sha256 ${source.sha256})`).join("\n");
|
|
1085
|
+
return [
|
|
1086
|
+
"Story preview source (edit these sources, never the generated preview artifact):",
|
|
1087
|
+
`Project: ${preview.projectPath}`,
|
|
1088
|
+
`Story: ${preview.storyPath}#${preview.storyExport}`,
|
|
1089
|
+
`Build revision: ${preview.buildRevision}`,
|
|
1090
|
+
`Viewport: ${String(preview.viewport.width)}x${String(preview.viewport.height)}`,
|
|
1091
|
+
"Sources:",
|
|
1092
|
+
sources,
|
|
1093
|
+
"After editing the underlying story or component source, rebuild the preview before treating it as visually verified."
|
|
1094
|
+
].join("\n");
|
|
1095
|
+
}
|
|
1078
1096
|
function authorCaptureContext(packet) {
|
|
1079
1097
|
const metadata = JSON.stringify(packet);
|
|
1080
1098
|
if (bytes(metadata) > 65536) throw new Error("Author capture packet exceeds 64 KiB.");
|
|
1081
|
-
const
|
|
1099
|
+
const annotations = packet.regions.map((region) => `(${String(region.ordinal)}) ${region.comment} [${anchorLocation(region.anchor)}]${region.quote ? `\nQuoted text: ${region.quote}` : ""}`).join("\n\n");
|
|
1100
|
+
const provenance = storyPreviewProvenance(packet);
|
|
1101
|
+
const content = provenance === void 0 ? annotations : `${provenance}\n\nAnnotations:\n${annotations}`;
|
|
1082
1102
|
return {
|
|
1083
1103
|
kind: "author-capture",
|
|
1084
1104
|
source: "author",
|
|
@@ -1356,6 +1376,7 @@ function anchorLabel(anchor) {
|
|
|
1356
1376
|
case "image-rect": return "Image region";
|
|
1357
1377
|
case "pdf-page-rect": return `Page ${anchor.page}`;
|
|
1358
1378
|
case "video-time-rect": return `Video ${Math.floor(anchor.timeSeconds / 60)}:${Math.floor(anchor.timeSeconds % 60).toString().padStart(2, "0")}`;
|
|
1379
|
+
case "story-preview-rect": return `${anchor.preview.storyPath}#${anchor.preview.storyExport}`;
|
|
1359
1380
|
}
|
|
1360
1381
|
}
|
|
1361
1382
|
function progressLabel(request) {
|
|
@@ -1613,7 +1634,7 @@ function AuthorToolPalette({ sessionId, kind, activeTool }) {
|
|
|
1613
1634
|
}
|
|
1614
1635
|
//#endregion
|
|
1615
1636
|
//#region src/extensions/workspaces/sessions/(frontend)/dock/_components/AuthorPanel.tsx
|
|
1616
|
-
function AuthorPanel({ sessionId, activeMinorModes, submitCapture, statuses }) {
|
|
1637
|
+
function AuthorPanel({ sessionId, activeMinorModes, submitCapture, statuses, renderSlot }) {
|
|
1617
1638
|
const [captureStatus, setCaptureStatus] = useState();
|
|
1618
1639
|
const [capturing, setCapturing] = useState(false);
|
|
1619
1640
|
const documents = useStore(authorWorkspace.store, (state) => {
|
|
@@ -1624,82 +1645,89 @@ function AuthorPanel({ sessionId, activeMinorModes, submitCapture, statuses }) {
|
|
|
1624
1645
|
const workspace = useStore(authorWorkspace.store, (state) => sessionId === null ? void 0 : state.sessions[sessionId]);
|
|
1625
1646
|
const grid = useStore(authorGrid.store, (state) => sessionId === null ? void 0 : state.sessions[sessionId]);
|
|
1626
1647
|
const focused = documents.find((document) => document.path === workspace?.focusedDocument?.path);
|
|
1627
|
-
if (!activeMinorModes?.includes("author")
|
|
1648
|
+
if (!activeMinorModes?.includes("author")) return null;
|
|
1628
1649
|
return /* @__PURE__ */ jsxs("section", {
|
|
1629
1650
|
"data-testid": "author-panel",
|
|
1630
1651
|
className: "flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-3",
|
|
1631
|
-
children: [
|
|
1632
|
-
/* @__PURE__ */ jsx("
|
|
1633
|
-
|
|
1634
|
-
children: "
|
|
1635
|
-
}),
|
|
1636
|
-
/* @__PURE__ */ jsx("p", {
|
|
1637
|
-
className: "text-base leading-normal text-doom-dim sm:text-sm",
|
|
1638
|
-
children: "Select a region, add a comment, then submit here. Requests queue while the agent is working."
|
|
1639
|
-
}),
|
|
1640
|
-
focused.kind === "video" ? /* @__PURE__ */ jsx("p", {
|
|
1641
|
-
className: "text-base text-doom-dim sm:text-sm",
|
|
1642
|
-
children: "Annotations reference video frames. They do not save changes to the source video."
|
|
1643
|
-
}) : null,
|
|
1644
|
-
/* @__PURE__ */ jsx(AuthorToolPalette, {
|
|
1645
|
-
sessionId,
|
|
1646
|
-
kind: focused.kind,
|
|
1647
|
-
activeTool: workspace.activeTool
|
|
1652
|
+
children: [
|
|
1653
|
+
/* @__PURE__ */ jsx("div", {
|
|
1654
|
+
"data-testid": "author-preview-providers",
|
|
1655
|
+
children: renderSlot("author.preview-provider")
|
|
1648
1656
|
}),
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
}) : null,
|
|
1660
|
-
/* @__PURE__ */ jsx(AuthorRegionDrafts, {
|
|
1661
|
-
sessionId,
|
|
1662
|
-
workspace
|
|
1663
|
-
}, focused.path),
|
|
1664
|
-
workspace.regions.length > 0 ? /* @__PURE__ */ jsxs("div", {
|
|
1665
|
-
className: "space-y-1.5 border-b border-doom-border-soft pb-3",
|
|
1666
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
1667
|
-
className: "min-h-11 min-w-11 w-full text-base [@media(pointer:fine)]:min-h-8 sm:text-sm",
|
|
1668
|
-
variant: "outline",
|
|
1669
|
-
"data-testid": "author-attach-capture",
|
|
1670
|
-
disabled: capturing || workspace.candidate !== void 0 || submitCapture === void 0,
|
|
1671
|
-
onClick: async () => {
|
|
1672
|
-
if (capturing || workspace.candidate || submitCapture === void 0) return;
|
|
1673
|
-
setCapturing(true);
|
|
1674
|
-
setCaptureStatus("Submitting annotations…");
|
|
1675
|
-
try {
|
|
1676
|
-
const packet = createAuthorCapturePacket(crypto.randomUUID(), Date.now(), focused, workspace.regions);
|
|
1677
|
-
await submitCapture({
|
|
1678
|
-
...await multiRegionCaptureProvider(workspace.regions).capture(),
|
|
1679
|
-
context: authorCaptureContext(packet)
|
|
1680
|
-
});
|
|
1681
|
-
setCaptureStatus("Request submitted. You can keep annotating here.");
|
|
1682
|
-
} catch (reason) {
|
|
1683
|
-
setCaptureStatus(reason instanceof Error ? reason.message : String(reason));
|
|
1684
|
-
} finally {
|
|
1685
|
-
setCapturing(false);
|
|
1686
|
-
}
|
|
1687
|
-
},
|
|
1688
|
-
children: capturing ? "Submitting…" : `Submit ${workspace.regions.length} annotation${workspace.regions.length === 1 ? "" : "s"}`
|
|
1689
|
-
}), workspace.candidate ? /* @__PURE__ */ jsx("p", {
|
|
1657
|
+
sessionId !== null && workspace !== void 0 && focused !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1658
|
+
/* @__PURE__ */ jsx("h2", {
|
|
1659
|
+
className: "text-base font-semibold text-doom-text",
|
|
1660
|
+
children: "Annotations"
|
|
1661
|
+
}),
|
|
1662
|
+
/* @__PURE__ */ jsx("p", {
|
|
1663
|
+
className: "text-base leading-normal text-doom-dim sm:text-sm",
|
|
1664
|
+
children: "Select a region, add a comment, then submit here. Requests queue while the agent is working."
|
|
1665
|
+
}),
|
|
1666
|
+
focused.kind === "video" ? /* @__PURE__ */ jsx("p", {
|
|
1690
1667
|
className: "text-base text-doom-dim sm:text-sm",
|
|
1691
|
-
children: "
|
|
1692
|
-
}) : null
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1668
|
+
children: "Annotations reference video frames. They do not save changes to the source video."
|
|
1669
|
+
}) : null,
|
|
1670
|
+
/* @__PURE__ */ jsx(AuthorToolPalette, {
|
|
1671
|
+
sessionId,
|
|
1672
|
+
kind: focused.kind,
|
|
1673
|
+
activeTool: workspace.activeTool
|
|
1674
|
+
}),
|
|
1675
|
+
autonomousVoiceGridVisible(statuses) && grid !== void 0 ? /* @__PURE__ */ jsxs("div", {
|
|
1676
|
+
"data-testid": "author-grid-snapshot",
|
|
1677
|
+
className: "rounded border border-doom-red/40 bg-doom-red/5 p-2 text-base text-doom-dim",
|
|
1678
|
+
children: [/* @__PURE__ */ jsx("strong", {
|
|
1679
|
+
className: "text-doom-red",
|
|
1680
|
+
children: "VOICE GRID A1–H8"
|
|
1681
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
1682
|
+
className: "mt-1 truncate",
|
|
1683
|
+
children: ["token ", grid.geometryToken]
|
|
1684
|
+
})]
|
|
1685
|
+
}) : null,
|
|
1686
|
+
/* @__PURE__ */ jsx(AuthorRegionDrafts, {
|
|
1687
|
+
sessionId,
|
|
1688
|
+
workspace
|
|
1689
|
+
}, focused.path),
|
|
1690
|
+
workspace.regions.length > 0 ? /* @__PURE__ */ jsxs("div", {
|
|
1691
|
+
className: "space-y-1.5 border-b border-doom-border-soft pb-3",
|
|
1692
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
1693
|
+
className: "min-h-11 min-w-11 w-full text-base [@media(pointer:fine)]:min-h-8 sm:text-sm",
|
|
1694
|
+
variant: "outline",
|
|
1695
|
+
"data-testid": "author-attach-capture",
|
|
1696
|
+
disabled: capturing || workspace.candidate !== void 0 || submitCapture === void 0,
|
|
1697
|
+
onClick: async () => {
|
|
1698
|
+
if (capturing || workspace.candidate || submitCapture === void 0) return;
|
|
1699
|
+
setCapturing(true);
|
|
1700
|
+
setCaptureStatus("Submitting annotations…");
|
|
1701
|
+
try {
|
|
1702
|
+
const packet = createAuthorCapturePacket(crypto.randomUUID(), Date.now(), focused, workspace.regions);
|
|
1703
|
+
await submitCapture({
|
|
1704
|
+
...await multiRegionCaptureProvider(workspace.regions).capture(),
|
|
1705
|
+
context: authorCaptureContext(packet)
|
|
1706
|
+
});
|
|
1707
|
+
setCaptureStatus("Request submitted. You can keep annotating here.");
|
|
1708
|
+
} catch (reason) {
|
|
1709
|
+
setCaptureStatus(reason instanceof Error ? reason.message : String(reason));
|
|
1710
|
+
} finally {
|
|
1711
|
+
setCapturing(false);
|
|
1712
|
+
}
|
|
1713
|
+
},
|
|
1714
|
+
children: capturing ? "Submitting…" : `Submit ${workspace.regions.length} annotation${workspace.regions.length === 1 ? "" : "s"}`
|
|
1715
|
+
}), workspace.candidate ? /* @__PURE__ */ jsx("p", {
|
|
1716
|
+
className: "text-base text-doom-dim sm:text-sm",
|
|
1717
|
+
children: "Add or discard the current selection before submitting."
|
|
1718
|
+
}) : null]
|
|
1719
|
+
}) : null,
|
|
1720
|
+
submitCapture === void 0 ? /* @__PURE__ */ jsx("output", {
|
|
1721
|
+
className: "text-sm text-doom-red",
|
|
1722
|
+
children: "Submission unavailable. Reload to update the app."
|
|
1723
|
+
}) : null,
|
|
1724
|
+
captureStatus ? /* @__PURE__ */ jsx("output", {
|
|
1725
|
+
className: "block text-sm text-doom-dim",
|
|
1726
|
+
children: captureStatus
|
|
1727
|
+
}) : null
|
|
1728
|
+
] }) : null,
|
|
1729
|
+
/* @__PURE__ */ jsx(AuthorRequestLog, { requests: workspace?.requests ?? [] })
|
|
1730
|
+
]
|
|
1703
1731
|
});
|
|
1704
1732
|
}
|
|
1705
1733
|
//#endregion
|
|
@@ -1712,16 +1740,31 @@ var authoring_web_default = defineDockFace({
|
|
|
1712
1740
|
panel: AuthorPanel,
|
|
1713
1741
|
requiredMinorMode: "author",
|
|
1714
1742
|
visibility: {
|
|
1715
|
-
subscribe(
|
|
1716
|
-
|
|
1717
|
-
return () => subscription.unsubscribe();
|
|
1743
|
+
subscribe() {
|
|
1744
|
+
return () => void 0;
|
|
1718
1745
|
},
|
|
1719
1746
|
isVisible(sessionId) {
|
|
1720
|
-
return sessionId !== null
|
|
1747
|
+
return sessionId !== null;
|
|
1721
1748
|
}
|
|
1722
1749
|
}
|
|
1723
1750
|
});
|
|
1724
1751
|
//#endregion
|
|
1752
|
+
//#region src/types/authorPreview.ts
|
|
1753
|
+
function parseAuthorPreviewAction(input) {
|
|
1754
|
+
if (typeof input !== "object" || input === null) return null;
|
|
1755
|
+
const candidate = input;
|
|
1756
|
+
if (candidate.version !== 1 || typeof candidate.label !== "string" || candidate.label.trim() === "") return null;
|
|
1757
|
+
if (candidate.detail !== void 0 && typeof candidate.detail !== "string") return null;
|
|
1758
|
+
if (typeof candidate.createTab !== "function") return null;
|
|
1759
|
+
if (candidate.supportsSource !== void 0 && typeof candidate.supportsSource !== "function") return null;
|
|
1760
|
+
if (candidate.embeddedPanel !== void 0 && typeof candidate.embeddedPanel !== "function") return null;
|
|
1761
|
+
return candidate;
|
|
1762
|
+
}
|
|
1763
|
+
const authorPreviewActionSlot = {
|
|
1764
|
+
slot: "author.preview-action",
|
|
1765
|
+
parse: parseAuthorPreviewAction
|
|
1766
|
+
};
|
|
1767
|
+
//#endregion
|
|
1725
1768
|
//#region src/types/apiRoutes.ts
|
|
1726
1769
|
/**
|
|
1727
1770
|
* This package's routes, as data.
|
|
@@ -1856,10 +1899,12 @@ function structuredFormat(path) {
|
|
|
1856
1899
|
if (lower.endsWith(".xlsx")) return "xlsx";
|
|
1857
1900
|
}
|
|
1858
1901
|
function authorKindForPath(path) {
|
|
1902
|
+
const lower = path.toLowerCase();
|
|
1903
|
+
if (/\.stories\.(?:js|jsx|ts|tsx)$/u.test(lower)) return "story-preview";
|
|
1859
1904
|
const format = structuredFormat(path);
|
|
1860
1905
|
if (format === "markdown-slides") return "slides";
|
|
1861
1906
|
if (format !== void 0) return format;
|
|
1862
|
-
const extension =
|
|
1907
|
+
const extension = lower.split(".").at(-1) ?? "";
|
|
1863
1908
|
if (extension === "md") return "markdown";
|
|
1864
1909
|
if (IMAGE_EXTENSIONS.has(extension)) return "image";
|
|
1865
1910
|
if (VIDEO_EXTENSIONS.has(extension)) return "video";
|
|
@@ -1927,7 +1972,7 @@ async function loadAuthorDocument(sessionId, path, signal) {
|
|
|
1927
1972
|
};
|
|
1928
1973
|
}
|
|
1929
1974
|
const mediaUrl = kind === "image" || kind === "video" || kind === "pdf" || kind === "opaque" ? url : void 0;
|
|
1930
|
-
const content = kind === "text" || kind === "markdown" ? await response.text() : void 0;
|
|
1975
|
+
const content = kind === "text" || kind === "markdown" || kind === "story-preview" ? await response.text() : void 0;
|
|
1931
1976
|
return {
|
|
1932
1977
|
path,
|
|
1933
1978
|
kind,
|
|
@@ -1985,7 +2030,7 @@ async function croppedImageBytes(documentInput, signal) {
|
|
|
1985
2030
|
}
|
|
1986
2031
|
}
|
|
1987
2032
|
async function bytesToSave(sessionId, document, signal) {
|
|
1988
|
-
if (document.kind === "text" || document.kind === "markdown") return document.content ?? "";
|
|
2033
|
+
if (document.kind === "text" || document.kind === "markdown" || document.kind === "story-preview") return document.content ?? "";
|
|
1989
2034
|
if (document.kind === "image" && document.crop !== void 0) return await croppedImageBytes(document, signal);
|
|
1990
2035
|
if (document.structuredFormat === void 0) throw new Error("This Author view cannot be saved.");
|
|
1991
2036
|
const operations = operationsFor(document);
|
|
@@ -3129,14 +3174,24 @@ function AuthorDocumentPanel(props) {
|
|
|
3129
3174
|
}
|
|
3130
3175
|
return /* @__PURE__ */ jsx(ActiveAuthorDocumentPanel, { ...props });
|
|
3131
3176
|
}
|
|
3132
|
-
function ActiveAuthorDocumentPanel(
|
|
3177
|
+
function ActiveAuthorDocumentPanel(props) {
|
|
3178
|
+
const { path, sessionId, statuses } = props;
|
|
3133
3179
|
const document = useStore(authorWorkspace.store, (state) => sessionId === null ? void 0 : state.documents[authorDocumentKey(sessionId, path)]);
|
|
3134
3180
|
const focusGeneration = useRef(void 0);
|
|
3135
3181
|
const workspace = useStore(authorWorkspace.store, (state) => sessionId === null ? void 0 : state.sessions[sessionId]);
|
|
3136
3182
|
const activeTool = workspace?.activeTool ?? "select";
|
|
3137
3183
|
const [markdownPreview, setMarkdownPreview] = useState(true);
|
|
3138
3184
|
const [status, setStatus] = useState();
|
|
3185
|
+
const [previewOpen, setPreviewOpen] = useState(false);
|
|
3139
3186
|
const kind = document?.kind;
|
|
3187
|
+
const previewSource = document === void 0 ? void 0 : {
|
|
3188
|
+
path: document.path,
|
|
3189
|
+
kind: document.kind,
|
|
3190
|
+
hasUnsavedChanges: document.version !== document.savedVersion,
|
|
3191
|
+
revision: document.savedVersion,
|
|
3192
|
+
sourceSha256: document.sourceSha256
|
|
3193
|
+
};
|
|
3194
|
+
const PreviewPanel = (previewSource === void 0 ? void 0 : (props.slotData?.(authorPreviewActionSlot) ?? []).find(({ data }) => data.embeddedPanel !== void 0 && (data.supportsSource === void 0 || data.supportsSource(previewSource))))?.data.embeddedPanel;
|
|
3140
3195
|
useEffect(() => {
|
|
3141
3196
|
if (document !== void 0 || sessionId === null) return;
|
|
3142
3197
|
const controller = new AbortController();
|
|
@@ -3202,7 +3257,8 @@ function ActiveAuthorDocumentPanel({ path, sessionId, statuses }) {
|
|
|
3202
3257
|
requestAuthorSave(sessionId, path);
|
|
3203
3258
|
setStatus("saving");
|
|
3204
3259
|
try {
|
|
3205
|
-
|
|
3260
|
+
const sha256 = await saveAuthorDocument(sessionId, document);
|
|
3261
|
+
completeAuthorSave(sessionId, path, sha256, savedVersion, savedFragments);
|
|
3206
3262
|
setStatus("saved");
|
|
3207
3263
|
} catch (error) {
|
|
3208
3264
|
failAuthorSave(sessionId, path, savedVersion);
|
|
@@ -3217,6 +3273,18 @@ function ActiveAuthorDocumentPanel({ path, sessionId, statuses }) {
|
|
|
3217
3273
|
preview: document.kind === "markdown" && markdownPreview && activeTool === "select" && !gridVisible,
|
|
3218
3274
|
displayedRegions
|
|
3219
3275
|
});
|
|
3276
|
+
const sourcePanel = document.kind === "text" || document.kind === "markdown" || document.kind === "story-preview" ? textPanel : document.structuredFormat !== void 0 ? /* @__PURE__ */ jsx(AuthorStructuredView, {
|
|
3277
|
+
sessionId,
|
|
3278
|
+
document,
|
|
3279
|
+
displayedRegions
|
|
3280
|
+
}) : /* @__PURE__ */ jsx(AuthorMediaView, {
|
|
3281
|
+
sessionId,
|
|
3282
|
+
document,
|
|
3283
|
+
activeTool,
|
|
3284
|
+
displayedRegions,
|
|
3285
|
+
pendingCandidate: workspace?.candidate !== void 0,
|
|
3286
|
+
seekRequest: workspace?.videoSeekRequest
|
|
3287
|
+
}, document.path);
|
|
3220
3288
|
return /* @__PURE__ */ jsxs("section", {
|
|
3221
3289
|
"data-testid": "author-document",
|
|
3222
3290
|
className: "flex min-h-0 flex-1 flex-col",
|
|
@@ -3228,6 +3296,15 @@ function ActiveAuthorDocumentPanel({ path, sessionId, statuses }) {
|
|
|
3228
3296
|
className: "min-w-0 flex-1 truncate text-base text-doom-hi",
|
|
3229
3297
|
children: document.title ?? document.path
|
|
3230
3298
|
}),
|
|
3299
|
+
PreviewPanel !== void 0 && previewSource !== void 0 ? /* @__PURE__ */ jsx(Button, {
|
|
3300
|
+
size: "xs",
|
|
3301
|
+
variant: previewOpen ? "primary" : "outline",
|
|
3302
|
+
"data-testid": "author-story-preview-toggle",
|
|
3303
|
+
"aria-pressed": previewOpen,
|
|
3304
|
+
"aria-label": previewOpen ? "show story source" : "show story preview",
|
|
3305
|
+
onClick: () => setPreviewOpen(!previewOpen),
|
|
3306
|
+
children: previewOpen ? "Source" : "Preview"
|
|
3307
|
+
}) : null,
|
|
3231
3308
|
document.kind === "markdown" ? /* @__PURE__ */ jsx(Button, {
|
|
3232
3309
|
size: "xs",
|
|
3233
3310
|
variant: "ghost",
|
|
@@ -3244,7 +3321,7 @@ function ActiveAuthorDocumentPanel({ path, sessionId, statuses }) {
|
|
|
3244
3321
|
"data-testid": "author-save",
|
|
3245
3322
|
disabled: document.revisions.length === 0 || document.savingVersion !== void 0,
|
|
3246
3323
|
onClick: () => void save(),
|
|
3247
|
-
children: "Save"
|
|
3324
|
+
children: previewOpen && previewSource?.hasUnsavedChanges ? "Save & refresh" : "Save"
|
|
3248
3325
|
})
|
|
3249
3326
|
]
|
|
3250
3327
|
}),
|
|
@@ -3254,18 +3331,10 @@ function ActiveAuthorDocumentPanel({ path, sessionId, statuses }) {
|
|
|
3254
3331
|
}),
|
|
3255
3332
|
/* @__PURE__ */ jsxs("div", {
|
|
3256
3333
|
className: "relative flex min-h-0 flex-1 overflow-hidden",
|
|
3257
|
-
children: [
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
}) : /* @__PURE__ */ jsx(AuthorMediaView, {
|
|
3262
|
-
sessionId,
|
|
3263
|
-
document,
|
|
3264
|
-
activeTool,
|
|
3265
|
-
displayedRegions,
|
|
3266
|
-
pendingCandidate: workspace?.candidate !== void 0,
|
|
3267
|
-
seekRequest: workspace?.videoSeekRequest
|
|
3268
|
-
}, document.path), /* @__PURE__ */ jsx(AuthorGridOverlay, {
|
|
3334
|
+
children: [previewOpen && PreviewPanel !== void 0 && previewSource !== void 0 ? /* @__PURE__ */ jsx(PreviewPanel, {
|
|
3335
|
+
...props,
|
|
3336
|
+
source: previewSource
|
|
3337
|
+
}) : sourcePanel, previewOpen && PreviewPanel !== void 0 && previewSource !== void 0 ? null : /* @__PURE__ */ jsx(AuthorGridOverlay, {
|
|
3269
3338
|
sessionId,
|
|
3270
3339
|
document,
|
|
3271
3340
|
visible: gridVisible
|
|
@@ -3411,6 +3480,21 @@ var mode_web_default = defineMinorModeFile({
|
|
|
3411
3480
|
order: 45
|
|
3412
3481
|
});
|
|
3413
3482
|
//#endregion
|
|
3483
|
+
//#region src/extensions/workspaces/sessions/(frontend)/slot/preview-action.web.ts
|
|
3484
|
+
/** Typed data slot for preview launchers that need Author's focused source. */
|
|
3485
|
+
var preview_action_web_default = defineSlotFile({
|
|
3486
|
+
slot: "author.preview-action",
|
|
3487
|
+
parse: parseAuthorPreviewAction
|
|
3488
|
+
});
|
|
3489
|
+
//#endregion
|
|
3490
|
+
//#region src/extensions/workspaces/sessions/(frontend)/slot/preview-provider.web.ts
|
|
3491
|
+
/**
|
|
3492
|
+
* Optional preview providers render launch controls here. The provider owns its
|
|
3493
|
+
* transient tab and preview lifecycle; Author owns the surrounding mode and
|
|
3494
|
+
* composer submission surface.
|
|
3495
|
+
*/
|
|
3496
|
+
var preview_provider_web_default = defineSlotFile({});
|
|
3497
|
+
//#endregion
|
|
3414
3498
|
//#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/describeAuthorToolsToolRender.ts
|
|
3415
3499
|
function describeAuthorToolsCallSummary(_args) {
|
|
3416
3500
|
return "";
|
|
@@ -3621,6 +3705,9 @@ const webPlugin = defineWebPlugin({
|
|
|
3621
3705
|
get minorModes() {
|
|
3622
3706
|
return [via({ name: "author" }, mode_web_default)];
|
|
3623
3707
|
},
|
|
3708
|
+
get slots() {
|
|
3709
|
+
return [via({ slot: "author.preview-action" }, preview_action_web_default), via({ slot: "author.preview-provider" }, preview_provider_web_default)];
|
|
3710
|
+
},
|
|
3624
3711
|
get start() {
|
|
3625
3712
|
return start_web_default;
|
|
3626
3713
|
},
|