@contractspec/lib.example-shared-ui 6.0.5 → 6.0.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/.turbo/turbo-build.log +90 -84
- package/AGENTS.md +43 -25
- package/CHANGELOG.md +11 -0
- package/README.md +63 -35
- package/dist/EvolutionDashboard.js +9 -9
- package/dist/EvolutionSidebar.js +15 -15
- package/dist/LocalDataIndicator.js +3 -3
- package/dist/MarkdownView.d.ts +0 -7
- package/dist/MarkdownView.js +76 -172
- package/dist/PersonalizationInsights.js +12 -12
- package/dist/SaveToStudioButton.js +2 -2
- package/dist/SpecDrivenTemplateShell.d.ts +1 -1
- package/dist/SpecDrivenTemplateShell.js +10 -10
- package/dist/SpecEditorPanel.js +3 -3
- package/dist/TemplateShell.js +10 -10
- package/dist/browser/EvolutionDashboard.js +9 -9
- package/dist/browser/EvolutionSidebar.js +15 -15
- package/dist/browser/LocalDataIndicator.js +3 -3
- package/dist/browser/MarkdownView.js +76 -172
- package/dist/browser/PersonalizationInsights.js +12 -12
- package/dist/browser/SaveToStudioButton.js +2 -2
- package/dist/browser/SpecDrivenTemplateShell.js +10 -10
- package/dist/browser/SpecEditorPanel.js +3 -3
- package/dist/browser/TemplateShell.js +10 -10
- package/dist/browser/hooks/index.js +29 -29
- package/dist/browser/index.js +193 -286
- package/dist/browser/lib/component-registry.js +1 -1
- package/dist/browser/markdown/formatPresentationName.js +9 -0
- package/dist/browser/markdown/useMarkdownPresentation.js +65 -0
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +29 -29
- package/dist/index.d.ts +12 -11
- package/dist/index.js +193 -286
- package/dist/lib/component-registry.js +1 -1
- package/dist/markdown/formatPresentationName.d.ts +1 -0
- package/dist/markdown/formatPresentationName.js +10 -0
- package/dist/markdown/useMarkdownPresentation.d.ts +21 -0
- package/dist/markdown/useMarkdownPresentation.js +66 -0
- package/dist/node/EvolutionDashboard.js +9 -9
- package/dist/node/EvolutionSidebar.js +15 -15
- package/dist/node/LocalDataIndicator.js +3 -3
- package/dist/node/MarkdownView.js +76 -172
- package/dist/node/PersonalizationInsights.js +12 -12
- package/dist/node/SaveToStudioButton.js +2 -2
- package/dist/node/SpecDrivenTemplateShell.js +10 -10
- package/dist/node/SpecEditorPanel.js +3 -3
- package/dist/node/TemplateShell.js +10 -10
- package/dist/node/hooks/index.js +29 -29
- package/dist/node/index.js +193 -286
- package/dist/node/lib/component-registry.js +1 -1
- package/dist/node/markdown/formatPresentationName.js +9 -0
- package/dist/node/markdown/useMarkdownPresentation.js +65 -0
- package/dist/utils/index.d.ts +1 -1
- package/package.json +40 -13
- package/src/EvolutionDashboard.tsx +415 -415
- package/src/EvolutionSidebar.tsx +245 -245
- package/src/LocalDataIndicator.tsx +28 -28
- package/src/MarkdownView.tsx +119 -372
- package/src/OverlayContextProvider.tsx +272 -272
- package/src/PersonalizationInsights.tsx +232 -232
- package/src/SaveToStudioButton.tsx +51 -51
- package/src/SpecDrivenTemplateShell.tsx +59 -59
- package/src/SpecEditorPanel.tsx +138 -138
- package/src/TemplateShell.tsx +50 -50
- package/src/bundles/ExampleTemplateBundle.ts +78 -78
- package/src/hooks/index.ts +3 -3
- package/src/hooks/useBehaviorTracking.ts +252 -252
- package/src/hooks/useEvolution.ts +437 -437
- package/src/hooks/useRegistryTemplates.ts +42 -42
- package/src/hooks/useSpecContent.ts +214 -214
- package/src/hooks/useWorkflowComposer.ts +567 -567
- package/src/index.ts +12 -11
- package/src/lib/component-registry.tsx +40 -40
- package/src/lib/runtime-context.tsx +31 -31
- package/src/lib/types.ts +57 -57
- package/src/markdown/formatPresentationName.ts +9 -0
- package/src/markdown/useMarkdownPresentation.ts +107 -0
- package/src/overlay-types.ts +15 -15
- package/src/utils/fetchPresentationData.ts +13 -13
- package/src/utils/generateSpecFromTemplate.ts +29 -29
- package/src/utils/index.ts +1 -1
- package/tsconfig.json +8 -8
package/dist/index.js
CHANGED
|
@@ -258,10 +258,10 @@ function generateRecommendedActions(anomaly) {
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// src/EvolutionDashboard.tsx
|
|
261
|
-
import { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
262
261
|
import { Button, LoaderBlock } from "@contractspec/lib.design-system";
|
|
263
|
-
import { Card } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
264
262
|
import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
263
|
+
import { Card } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
264
|
+
import { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
265
265
|
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
266
266
|
"use client";
|
|
267
267
|
function EvolutionDashboard({
|
|
@@ -340,7 +340,7 @@ function EvolutionDashboard({
|
|
|
340
340
|
/* @__PURE__ */ jsxDEV("div", {
|
|
341
341
|
children: [
|
|
342
342
|
/* @__PURE__ */ jsxDEV("h2", {
|
|
343
|
-
className: "text-xl
|
|
343
|
+
className: "font-semibold text-xl",
|
|
344
344
|
children: "AI Evolution Engine"
|
|
345
345
|
}, undefined, false, undefined, this),
|
|
346
346
|
/* @__PURE__ */ jsxDEV("p", {
|
|
@@ -398,7 +398,7 @@ function EvolutionDashboard({
|
|
|
398
398
|
]
|
|
399
399
|
}, undefined, true, undefined, this),
|
|
400
400
|
/* @__PURE__ */ jsxDEV("p", {
|
|
401
|
-
className: "text-muted-foreground
|
|
401
|
+
className: "mt-2 text-muted-foreground text-xs",
|
|
402
402
|
children: "Simulate sandbox operations, analyze patterns, and generate AI improvement suggestions."
|
|
403
403
|
}, undefined, false, undefined, this)
|
|
404
404
|
]
|
|
@@ -515,7 +515,7 @@ function UsageStatCard({ stat }) {
|
|
|
515
515
|
className: "mb-2 flex items-center justify-between",
|
|
516
516
|
children: [
|
|
517
517
|
/* @__PURE__ */ jsxDEV("span", {
|
|
518
|
-
className: "font-mono text-sm
|
|
518
|
+
className: "font-medium font-mono text-sm",
|
|
519
519
|
children: stat.operation.name
|
|
520
520
|
}, undefined, false, undefined, this),
|
|
521
521
|
/* @__PURE__ */ jsxDEV(Badge, {
|
|
@@ -617,7 +617,7 @@ function AnomalyCard({ anomaly }) {
|
|
|
617
617
|
/* @__PURE__ */ jsxDEV("div", {
|
|
618
618
|
children: [
|
|
619
619
|
/* @__PURE__ */ jsxDEV("p", {
|
|
620
|
-
className: "text-sm
|
|
620
|
+
className: "font-medium text-sm",
|
|
621
621
|
children: anomaly.description
|
|
622
622
|
}, undefined, false, undefined, this),
|
|
623
623
|
/* @__PURE__ */ jsxDEV("p", {
|
|
@@ -687,7 +687,7 @@ function SuggestionCard({
|
|
|
687
687
|
]
|
|
688
688
|
}, undefined, true, undefined, this),
|
|
689
689
|
/* @__PURE__ */ jsxDEV("p", {
|
|
690
|
-
className: "text-muted-foreground
|
|
690
|
+
className: "mt-1 text-muted-foreground text-sm",
|
|
691
691
|
children: suggestion.proposal.rationale
|
|
692
692
|
}, undefined, false, undefined, this)
|
|
693
693
|
]
|
|
@@ -703,7 +703,7 @@ function SuggestionCard({
|
|
|
703
703
|
className: "mt-3",
|
|
704
704
|
children: [
|
|
705
705
|
/* @__PURE__ */ jsxDEV("p", {
|
|
706
|
-
className: "mb-1
|
|
706
|
+
className: "mb-1 font-semibold text-violet-400 text-xs uppercase",
|
|
707
707
|
children: "Recommended Actions"
|
|
708
708
|
}, undefined, false, undefined, this),
|
|
709
709
|
/* @__PURE__ */ jsxDEV("ul", {
|
|
@@ -784,7 +784,7 @@ function HintCard({ hint }) {
|
|
|
784
784
|
children: hint.summary
|
|
785
785
|
}, undefined, false, undefined, this),
|
|
786
786
|
/* @__PURE__ */ jsxDEV("p", {
|
|
787
|
-
className: "text-muted-foreground
|
|
787
|
+
className: "mt-1 text-muted-foreground text-xs",
|
|
788
788
|
children: hint.justification
|
|
789
789
|
}, undefined, false, undefined, this),
|
|
790
790
|
hint.recommendedActions.length > 0 && /* @__PURE__ */ jsxDEV("ul", {
|
|
@@ -801,10 +801,10 @@ function HintCard({ hint }) {
|
|
|
801
801
|
}
|
|
802
802
|
|
|
803
803
|
// src/EvolutionSidebar.tsx
|
|
804
|
-
import { useCallback as useCallback3, useMemo as useMemo3 } from "react";
|
|
805
804
|
import { Button as Button2 } from "@contractspec/lib.design-system";
|
|
806
|
-
import { Card as Card2 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
807
805
|
import { Badge as Badge2 } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
806
|
+
import { Card as Card2 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
807
|
+
import { useCallback as useCallback3, useMemo as useMemo3 } from "react";
|
|
808
808
|
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
809
809
|
"use client";
|
|
810
810
|
function EvolutionSidebar({
|
|
@@ -863,7 +863,7 @@ function EvolutionSidebar({
|
|
|
863
863
|
className: "w-80 overflow-hidden",
|
|
864
864
|
children: [
|
|
865
865
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
866
|
-
className: "flex items-center justify-between border-
|
|
866
|
+
className: "flex items-center justify-between border-violet-500/20 border-b bg-violet-500/5 px-3 py-2",
|
|
867
867
|
children: [
|
|
868
868
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
869
869
|
className: "flex items-center gap-2",
|
|
@@ -872,7 +872,7 @@ function EvolutionSidebar({
|
|
|
872
872
|
children: "\uD83E\uDD16"
|
|
873
873
|
}, undefined, false, undefined, this),
|
|
874
874
|
/* @__PURE__ */ jsxDEV2("span", {
|
|
875
|
-
className: "text-sm
|
|
875
|
+
className: "font-semibold text-sm",
|
|
876
876
|
children: "Evolution"
|
|
877
877
|
}, undefined, false, undefined, this)
|
|
878
878
|
]
|
|
@@ -888,7 +888,7 @@ function EvolutionSidebar({
|
|
|
888
888
|
}, undefined, false, undefined, this),
|
|
889
889
|
/* @__PURE__ */ jsxDEV2("button", {
|
|
890
890
|
onClick: onToggle,
|
|
891
|
-
className: "text-muted-foreground hover:text-foreground
|
|
891
|
+
className: "p-1 text-muted-foreground hover:text-foreground",
|
|
892
892
|
type: "button",
|
|
893
893
|
title: "Collapse",
|
|
894
894
|
children: "\u2715"
|
|
@@ -933,14 +933,14 @@ function EvolutionSidebar({
|
|
|
933
933
|
]
|
|
934
934
|
}, undefined, true, undefined, this),
|
|
935
935
|
loading && /* @__PURE__ */ jsxDEV2("div", {
|
|
936
|
-
className: "
|
|
936
|
+
className: "py-4 text-center text-muted-foreground text-sm",
|
|
937
937
|
children: "Generating suggestions..."
|
|
938
938
|
}, undefined, false, undefined, this),
|
|
939
939
|
topAnomalies.length > 0 && /* @__PURE__ */ jsxDEV2("div", {
|
|
940
940
|
className: "mb-4",
|
|
941
941
|
children: [
|
|
942
942
|
/* @__PURE__ */ jsxDEV2("p", {
|
|
943
|
-
className: "mb-2
|
|
943
|
+
className: "mb-2 font-semibold text-violet-400 text-xs uppercase",
|
|
944
944
|
children: "Top Issues"
|
|
945
945
|
}, undefined, false, undefined, this),
|
|
946
946
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
@@ -961,7 +961,7 @@ function EvolutionSidebar({
|
|
|
961
961
|
]
|
|
962
962
|
}, undefined, true, undefined, this),
|
|
963
963
|
/* @__PURE__ */ jsxDEV2("p", {
|
|
964
|
-
className: "text-muted-foreground
|
|
964
|
+
className: "mt-1 truncate text-muted-foreground",
|
|
965
965
|
children: anomaly.description
|
|
966
966
|
}, undefined, false, undefined, this)
|
|
967
967
|
]
|
|
@@ -972,7 +972,7 @@ function EvolutionSidebar({
|
|
|
972
972
|
pendingSuggestions.length > 0 && /* @__PURE__ */ jsxDEV2("div", {
|
|
973
973
|
children: [
|
|
974
974
|
/* @__PURE__ */ jsxDEV2("p", {
|
|
975
|
-
className: "mb-2
|
|
975
|
+
className: "mb-2 font-semibold text-violet-400 text-xs uppercase",
|
|
976
976
|
children: "Pending Suggestions"
|
|
977
977
|
}, undefined, false, undefined, this),
|
|
978
978
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
@@ -984,7 +984,7 @@ function EvolutionSidebar({
|
|
|
984
984
|
onReject: handleReject
|
|
985
985
|
}, suggestion.id, false, undefined, this)),
|
|
986
986
|
pendingSuggestions.length > 3 && /* @__PURE__ */ jsxDEV2("p", {
|
|
987
|
-
className: "text-muted-foreground text-
|
|
987
|
+
className: "text-center text-muted-foreground text-xs",
|
|
988
988
|
children: [
|
|
989
989
|
"+",
|
|
990
990
|
pendingSuggestions.length - 3,
|
|
@@ -996,13 +996,13 @@ function EvolutionSidebar({
|
|
|
996
996
|
]
|
|
997
997
|
}, undefined, true, undefined, this),
|
|
998
998
|
anomalies.length === 0 && pendingSuggestions.length === 0 && !loading && /* @__PURE__ */ jsxDEV2("div", {
|
|
999
|
-
className: "
|
|
999
|
+
className: "py-4 text-center text-muted-foreground text-xs",
|
|
1000
1000
|
children: "No issues detected. Keep coding!"
|
|
1001
1001
|
}, undefined, false, undefined, this)
|
|
1002
1002
|
]
|
|
1003
1003
|
}, undefined, true, undefined, this),
|
|
1004
1004
|
onOpenEvolution && /* @__PURE__ */ jsxDEV2("div", {
|
|
1005
|
-
className: "border-
|
|
1005
|
+
className: "border-violet-500/20 border-t p-2",
|
|
1006
1006
|
children: /* @__PURE__ */ jsxDEV2(Button2, {
|
|
1007
1007
|
variant: "ghost",
|
|
1008
1008
|
size: "sm",
|
|
@@ -1028,7 +1028,7 @@ function CompactSuggestionCard({
|
|
|
1028
1028
|
className: "min-w-0 flex-1",
|
|
1029
1029
|
children: [
|
|
1030
1030
|
/* @__PURE__ */ jsxDEV2("p", {
|
|
1031
|
-
className: "truncate text-xs
|
|
1031
|
+
className: "truncate font-medium text-xs",
|
|
1032
1032
|
children: suggestion.proposal.summary
|
|
1033
1033
|
}, undefined, false, undefined, this),
|
|
1034
1034
|
/* @__PURE__ */ jsxDEV2("div", {
|
|
@@ -1055,13 +1055,13 @@ function CompactSuggestionCard({
|
|
|
1055
1055
|
children: [
|
|
1056
1056
|
/* @__PURE__ */ jsxDEV2("button", {
|
|
1057
1057
|
onClick: () => onReject(suggestion.id),
|
|
1058
|
-
className: "rounded px-2 py-0.5 text-
|
|
1058
|
+
className: "rounded px-2 py-0.5 text-red-400 text-xs hover:bg-red-400/10",
|
|
1059
1059
|
type: "button",
|
|
1060
1060
|
children: "Reject"
|
|
1061
1061
|
}, undefined, false, undefined, this),
|
|
1062
1062
|
/* @__PURE__ */ jsxDEV2("button", {
|
|
1063
1063
|
onClick: () => onApprove(suggestion.id),
|
|
1064
|
-
className: "rounded bg-violet-500/20 px-2 py-0.5 text-
|
|
1064
|
+
className: "rounded bg-violet-500/20 px-2 py-0.5 text-violet-400 text-xs hover:bg-violet-500/30",
|
|
1065
1065
|
type: "button",
|
|
1066
1066
|
children: "Approve"
|
|
1067
1067
|
}, undefined, false, undefined, this)
|
|
@@ -1100,7 +1100,7 @@ function LocalDataIndicator() {
|
|
|
1100
1100
|
}
|
|
1101
1101
|
};
|
|
1102
1102
|
return /* @__PURE__ */ jsxDEV3("div", {
|
|
1103
|
-
className: "
|
|
1103
|
+
className: "inline-flex items-center gap-2 rounded-full border border-border bg-muted/40 px-3 py-1 text-muted-foreground text-xs",
|
|
1104
1104
|
children: [
|
|
1105
1105
|
/* @__PURE__ */ jsxDEV3(Shield, {
|
|
1106
1106
|
className: "h-3.5 w-3.5 text-violet-400"
|
|
@@ -1110,14 +1110,14 @@ function LocalDataIndicator() {
|
|
|
1110
1110
|
"Local runtime \xB7",
|
|
1111
1111
|
" ",
|
|
1112
1112
|
/* @__PURE__ */ jsxDEV3("span", {
|
|
1113
|
-
className: "text-foreground
|
|
1113
|
+
className: "font-semibold text-foreground",
|
|
1114
1114
|
children: template.name
|
|
1115
1115
|
}, undefined, false, undefined, this)
|
|
1116
1116
|
]
|
|
1117
1117
|
}, undefined, true, undefined, this),
|
|
1118
1118
|
/* @__PURE__ */ jsxDEV3("button", {
|
|
1119
1119
|
type: "button",
|
|
1120
|
-
className: "
|
|
1120
|
+
className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-0.5 font-semibold text-[11px] text-muted-foreground hover:text-foreground",
|
|
1121
1121
|
onClick: handleReset,
|
|
1122
1122
|
disabled: isResetting,
|
|
1123
1123
|
children: [
|
|
@@ -1131,31 +1131,24 @@ function LocalDataIndicator() {
|
|
|
1131
1131
|
}, undefined, true, undefined, this);
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
|
-
// src/
|
|
1134
|
+
// src/markdown/formatPresentationName.ts
|
|
1135
|
+
function formatPresentationName(name) {
|
|
1136
|
+
const parts = name.split(".");
|
|
1137
|
+
const lastPart = parts[parts.length - 1] ?? name;
|
|
1138
|
+
return lastPart.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// src/markdown/useMarkdownPresentation.ts
|
|
1135
1142
|
import { useCallback as useCallback4, useEffect as useEffect2, useState as useState3 } from "react";
|
|
1136
|
-
import {
|
|
1137
|
-
Button as Button3,
|
|
1138
|
-
ErrorState,
|
|
1139
|
-
LoaderBlock as LoaderBlock2
|
|
1140
|
-
} from "@contractspec/lib.design-system";
|
|
1141
|
-
import { Card as Card3 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
1142
|
-
import { Badge as Badge3 } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
1143
|
-
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
1144
1143
|
"use client";
|
|
1145
|
-
function
|
|
1146
|
-
|
|
1144
|
+
function useMarkdownPresentation({
|
|
1145
|
+
engine,
|
|
1146
|
+
fetchData,
|
|
1147
1147
|
presentationId,
|
|
1148
|
-
|
|
1148
|
+
presentations,
|
|
1149
|
+
resolvePresentation,
|
|
1150
|
+
templateId
|
|
1149
1151
|
}) {
|
|
1150
|
-
const {
|
|
1151
|
-
engine,
|
|
1152
|
-
template,
|
|
1153
|
-
templateId: contextTemplateId,
|
|
1154
|
-
resolvePresentation,
|
|
1155
|
-
fetchData
|
|
1156
|
-
} = useTemplateRuntime();
|
|
1157
|
-
const templateId = propTemplateId ?? contextTemplateId;
|
|
1158
|
-
const presentations = template?.presentations ?? [];
|
|
1159
1152
|
const [selectedPresentation, setSelectedPresentation] = useState3("");
|
|
1160
1153
|
const [markdownContent, setMarkdownContent] = useState3("");
|
|
1161
1154
|
const [loading, setLoading] = useState3(false);
|
|
@@ -1163,10 +1156,16 @@ function MarkdownView({
|
|
|
1163
1156
|
useEffect2(() => {
|
|
1164
1157
|
if (presentationId && presentations.includes(presentationId)) {
|
|
1165
1158
|
setSelectedPresentation(presentationId);
|
|
1166
|
-
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
if (presentations.length === 0) {
|
|
1162
|
+
setSelectedPresentation("");
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1165
|
+
if (!presentations.includes(selectedPresentation)) {
|
|
1167
1166
|
setSelectedPresentation(presentations[0] ?? "");
|
|
1168
1167
|
}
|
|
1169
|
-
}, [presentationId, presentations, selectedPresentation]);
|
|
1168
|
+
}, [presentationId, presentations, selectedPresentation, templateId]);
|
|
1170
1169
|
const renderMarkdown = useCallback4(async () => {
|
|
1171
1170
|
if (!selectedPresentation || !engine)
|
|
1172
1171
|
return;
|
|
@@ -1188,16 +1187,61 @@ function MarkdownView({
|
|
|
1188
1187
|
} finally {
|
|
1189
1188
|
setLoading(false);
|
|
1190
1189
|
}
|
|
1191
|
-
}, [
|
|
1190
|
+
}, [engine, fetchData, resolvePresentation, selectedPresentation]);
|
|
1191
|
+
useEffect2(() => {
|
|
1192
|
+
renderMarkdown();
|
|
1193
|
+
}, [renderMarkdown]);
|
|
1194
|
+
return {
|
|
1195
|
+
error,
|
|
1196
|
+
loading,
|
|
1197
|
+
markdownContent,
|
|
1198
|
+
renderMarkdown,
|
|
1192
1199
|
selectedPresentation,
|
|
1193
|
-
|
|
1200
|
+
setSelectedPresentation
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// src/MarkdownView.tsx
|
|
1205
|
+
import {
|
|
1206
|
+
Button as Button3,
|
|
1207
|
+
ErrorState,
|
|
1208
|
+
LoaderBlock as LoaderBlock2,
|
|
1209
|
+
MarkdownRenderer
|
|
1210
|
+
} from "@contractspec/lib.design-system";
|
|
1211
|
+
import { Badge as Badge3 } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
1212
|
+
import { Card as Card3 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
1213
|
+
import { useCallback as useCallback5 } from "react";
|
|
1214
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
1215
|
+
"use client";
|
|
1216
|
+
function MarkdownView({
|
|
1217
|
+
templateId: propTemplateId,
|
|
1218
|
+
presentationId,
|
|
1219
|
+
className
|
|
1220
|
+
}) {
|
|
1221
|
+
const {
|
|
1194
1222
|
engine,
|
|
1223
|
+
template,
|
|
1224
|
+
templateId: contextTemplateId,
|
|
1195
1225
|
resolvePresentation,
|
|
1196
1226
|
fetchData
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1227
|
+
} = useTemplateRuntime();
|
|
1228
|
+
const templateId = propTemplateId ?? contextTemplateId;
|
|
1229
|
+
const presentations = template?.presentations ?? [];
|
|
1230
|
+
const {
|
|
1231
|
+
error,
|
|
1232
|
+
loading,
|
|
1233
|
+
markdownContent,
|
|
1234
|
+
renderMarkdown,
|
|
1235
|
+
selectedPresentation,
|
|
1236
|
+
setSelectedPresentation
|
|
1237
|
+
} = useMarkdownPresentation({
|
|
1238
|
+
engine,
|
|
1239
|
+
fetchData,
|
|
1240
|
+
presentationId,
|
|
1241
|
+
presentations,
|
|
1242
|
+
resolvePresentation,
|
|
1243
|
+
templateId
|
|
1244
|
+
});
|
|
1201
1245
|
if (!presentations.length) {
|
|
1202
1246
|
return /* @__PURE__ */ jsxDEV4(Card3, {
|
|
1203
1247
|
className,
|
|
@@ -1210,7 +1254,7 @@ function MarkdownView({
|
|
|
1210
1254
|
}, undefined, false, undefined, this)
|
|
1211
1255
|
}, undefined, false, undefined, this);
|
|
1212
1256
|
}
|
|
1213
|
-
const handleCopy =
|
|
1257
|
+
const handleCopy = useCallback5(() => {
|
|
1214
1258
|
if (markdownContent) {
|
|
1215
1259
|
navigator.clipboard.writeText(markdownContent);
|
|
1216
1260
|
}
|
|
@@ -1222,7 +1266,7 @@ function MarkdownView({
|
|
|
1222
1266
|
className: "mb-4 flex flex-wrap items-center gap-2",
|
|
1223
1267
|
children: [
|
|
1224
1268
|
/* @__PURE__ */ jsxDEV4("span", {
|
|
1225
|
-
className: "text-muted-foreground text-sm
|
|
1269
|
+
className: "font-medium text-muted-foreground text-sm",
|
|
1226
1270
|
children: "Presentation:"
|
|
1227
1271
|
}, undefined, false, undefined, this),
|
|
1228
1272
|
presentations.map((name) => /* @__PURE__ */ jsxDEV4(Button3, {
|
|
@@ -1279,145 +1323,6 @@ function MarkdownView({
|
|
|
1279
1323
|
]
|
|
1280
1324
|
}, undefined, true, undefined, this);
|
|
1281
1325
|
}
|
|
1282
|
-
function MarkdownRenderer({ content }) {
|
|
1283
|
-
const lines = content.split(`
|
|
1284
|
-
`);
|
|
1285
|
-
const rendered = [];
|
|
1286
|
-
let i = 0;
|
|
1287
|
-
while (i < lines.length) {
|
|
1288
|
-
const line = lines[i] ?? "";
|
|
1289
|
-
if (line.startsWith("|") && lines[i + 1]?.match(/^\|[\s-|]+\|$/)) {
|
|
1290
|
-
const tableLines = [line];
|
|
1291
|
-
i++;
|
|
1292
|
-
while (i < lines.length && (lines[i]?.startsWith("|") ?? false)) {
|
|
1293
|
-
tableLines.push(lines[i] ?? "");
|
|
1294
|
-
i++;
|
|
1295
|
-
}
|
|
1296
|
-
rendered.push(renderTable(tableLines, rendered.length));
|
|
1297
|
-
continue;
|
|
1298
|
-
}
|
|
1299
|
-
if (line.startsWith("# ")) {
|
|
1300
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("h1", {
|
|
1301
|
-
className: "mb-4 text-2xl font-bold",
|
|
1302
|
-
children: line.slice(2)
|
|
1303
|
-
}, i, false, undefined, this));
|
|
1304
|
-
} else if (line.startsWith("## ")) {
|
|
1305
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("h2", {
|
|
1306
|
-
className: "mt-6 mb-3 text-xl font-semibold",
|
|
1307
|
-
children: line.slice(3)
|
|
1308
|
-
}, i, false, undefined, this));
|
|
1309
|
-
} else if (line.startsWith("### ")) {
|
|
1310
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("h3", {
|
|
1311
|
-
className: "mt-4 mb-2 text-lg font-medium",
|
|
1312
|
-
children: line.slice(4)
|
|
1313
|
-
}, i, false, undefined, this));
|
|
1314
|
-
} else if (line.startsWith("> ")) {
|
|
1315
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("blockquote", {
|
|
1316
|
-
className: "text-muted-foreground my-2 border-l-4 border-violet-500/50 pl-4 italic",
|
|
1317
|
-
children: line.slice(2)
|
|
1318
|
-
}, i, false, undefined, this));
|
|
1319
|
-
} else if (line.startsWith("- ")) {
|
|
1320
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("li", {
|
|
1321
|
-
className: "ml-4 list-disc",
|
|
1322
|
-
children: formatInlineMarkdown(line.slice(2))
|
|
1323
|
-
}, i, false, undefined, this));
|
|
1324
|
-
} else if (line.startsWith("**") && line.includes(":**")) {
|
|
1325
|
-
const [label, ...rest] = line.split(":**");
|
|
1326
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("p", {
|
|
1327
|
-
className: "my-1",
|
|
1328
|
-
children: [
|
|
1329
|
-
/* @__PURE__ */ jsxDEV4("strong", {
|
|
1330
|
-
children: [
|
|
1331
|
-
label?.slice(2),
|
|
1332
|
-
":"
|
|
1333
|
-
]
|
|
1334
|
-
}, undefined, true, undefined, this),
|
|
1335
|
-
rest.join(":**")
|
|
1336
|
-
]
|
|
1337
|
-
}, i, true, undefined, this));
|
|
1338
|
-
} else if (line.startsWith("_") && line.endsWith("_")) {
|
|
1339
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("p", {
|
|
1340
|
-
className: "text-muted-foreground my-1 italic",
|
|
1341
|
-
children: line.slice(1, -1)
|
|
1342
|
-
}, i, false, undefined, this));
|
|
1343
|
-
} else if (!line.trim()) {
|
|
1344
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("div", {
|
|
1345
|
-
className: "h-2"
|
|
1346
|
-
}, i, false, undefined, this));
|
|
1347
|
-
} else {
|
|
1348
|
-
rendered.push(/* @__PURE__ */ jsxDEV4("p", {
|
|
1349
|
-
className: "my-1",
|
|
1350
|
-
children: formatInlineMarkdown(line)
|
|
1351
|
-
}, i, false, undefined, this));
|
|
1352
|
-
}
|
|
1353
|
-
i++;
|
|
1354
|
-
}
|
|
1355
|
-
return /* @__PURE__ */ jsxDEV4("div", {
|
|
1356
|
-
className: "prose prose-sm dark:prose-invert max-w-none",
|
|
1357
|
-
children: rendered
|
|
1358
|
-
}, undefined, false, undefined, this);
|
|
1359
|
-
}
|
|
1360
|
-
function renderTable(lines, keyPrefix) {
|
|
1361
|
-
if (lines.length < 2)
|
|
1362
|
-
return null;
|
|
1363
|
-
const parseRow = (row) => row.split("|").slice(1, -1).map((cell) => cell.trim());
|
|
1364
|
-
const headers = parseRow(lines[0] ?? "");
|
|
1365
|
-
const dataRows = lines.slice(2).map(parseRow);
|
|
1366
|
-
return /* @__PURE__ */ jsxDEV4("div", {
|
|
1367
|
-
className: "my-4 overflow-x-auto",
|
|
1368
|
-
children: /* @__PURE__ */ jsxDEV4("table", {
|
|
1369
|
-
className: "border-border min-w-full border-collapse border text-sm",
|
|
1370
|
-
children: [
|
|
1371
|
-
/* @__PURE__ */ jsxDEV4("thead", {
|
|
1372
|
-
children: /* @__PURE__ */ jsxDEV4("tr", {
|
|
1373
|
-
className: "bg-muted/50",
|
|
1374
|
-
children: headers.map((header, idx) => /* @__PURE__ */ jsxDEV4("th", {
|
|
1375
|
-
className: "border-border border px-3 py-2 text-left font-semibold",
|
|
1376
|
-
children: header
|
|
1377
|
-
}, idx, false, undefined, this))
|
|
1378
|
-
}, undefined, false, undefined, this)
|
|
1379
|
-
}, undefined, false, undefined, this),
|
|
1380
|
-
/* @__PURE__ */ jsxDEV4("tbody", {
|
|
1381
|
-
children: dataRows.map((row, rowIdx) => /* @__PURE__ */ jsxDEV4("tr", {
|
|
1382
|
-
className: "hover:bg-muted/30",
|
|
1383
|
-
children: row.map((cell, cellIdx) => /* @__PURE__ */ jsxDEV4("td", {
|
|
1384
|
-
className: "border-border border px-3 py-2",
|
|
1385
|
-
children: formatInlineMarkdown(cell)
|
|
1386
|
-
}, cellIdx, false, undefined, this))
|
|
1387
|
-
}, rowIdx, false, undefined, this))
|
|
1388
|
-
}, undefined, false, undefined, this)
|
|
1389
|
-
]
|
|
1390
|
-
}, undefined, true, undefined, this)
|
|
1391
|
-
}, `table-${keyPrefix}`, false, undefined, this);
|
|
1392
|
-
}
|
|
1393
|
-
function formatInlineMarkdown(text) {
|
|
1394
|
-
const parts = text.split(/(\*\*[^*]+\*\*)/g);
|
|
1395
|
-
return parts.map((part, i) => {
|
|
1396
|
-
if (part.startsWith("**") && part.endsWith("**")) {
|
|
1397
|
-
return /* @__PURE__ */ jsxDEV4("strong", {
|
|
1398
|
-
children: part.slice(2, -2)
|
|
1399
|
-
}, i, false, undefined, this);
|
|
1400
|
-
}
|
|
1401
|
-
if (part.includes("`")) {
|
|
1402
|
-
const codeParts = part.split(/(`[^`]+`)/g);
|
|
1403
|
-
return codeParts.map((cp, j) => {
|
|
1404
|
-
if (cp.startsWith("`") && cp.endsWith("`")) {
|
|
1405
|
-
return /* @__PURE__ */ jsxDEV4("code", {
|
|
1406
|
-
className: "rounded bg-violet-500/10 px-1.5 py-0.5 font-mono text-sm",
|
|
1407
|
-
children: cp.slice(1, -1)
|
|
1408
|
-
}, `${i}-${j}`, false, undefined, this);
|
|
1409
|
-
}
|
|
1410
|
-
return cp;
|
|
1411
|
-
});
|
|
1412
|
-
}
|
|
1413
|
-
return part;
|
|
1414
|
-
});
|
|
1415
|
-
}
|
|
1416
|
-
function formatPresentationName(name) {
|
|
1417
|
-
const parts = name.split(".");
|
|
1418
|
-
const lastPart = parts[parts.length - 1] ?? name;
|
|
1419
|
-
return lastPart.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
1420
|
-
}
|
|
1421
1326
|
|
|
1422
1327
|
// src/OverlayContextProvider.tsx
|
|
1423
1328
|
import * as React from "react";
|
|
@@ -1618,7 +1523,7 @@ function getTemplateOverlays(templateId, _role) {
|
|
|
1618
1523
|
}
|
|
1619
1524
|
|
|
1620
1525
|
// src/hooks/useBehaviorTracking.ts
|
|
1621
|
-
import { useCallback as
|
|
1526
|
+
import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo5, useRef as useRef2, useState as useState4 } from "react";
|
|
1622
1527
|
"use client";
|
|
1623
1528
|
var BEHAVIOR_STORAGE_KEY = "contractspec-behavior-data";
|
|
1624
1529
|
var ALL_FEATURES = [
|
|
@@ -1663,7 +1568,7 @@ function useBehaviorTracking(templateId) {
|
|
|
1663
1568
|
} catch {}
|
|
1664
1569
|
}
|
|
1665
1570
|
}, [events]);
|
|
1666
|
-
const trackEvent =
|
|
1571
|
+
const trackEvent = useCallback6((type, metadata) => {
|
|
1667
1572
|
const event = {
|
|
1668
1573
|
type,
|
|
1669
1574
|
timestamp: new Date,
|
|
@@ -1673,10 +1578,10 @@ function useBehaviorTracking(templateId) {
|
|
|
1673
1578
|
setEvents((prev) => [...prev, event]);
|
|
1674
1579
|
setEventCount((prev) => prev + 1);
|
|
1675
1580
|
}, [templateId]);
|
|
1676
|
-
const getEventsByType =
|
|
1581
|
+
const getEventsByType = useCallback6((type) => {
|
|
1677
1582
|
return events.filter((e) => e.type === type);
|
|
1678
1583
|
}, [events]);
|
|
1679
|
-
const getSummary =
|
|
1584
|
+
const getSummary = useCallback6(() => {
|
|
1680
1585
|
const now = new Date;
|
|
1681
1586
|
const sessionDuration = now.getTime() - sessionStartRef.current.getTime();
|
|
1682
1587
|
const templateCounts = new Map;
|
|
@@ -1731,7 +1636,7 @@ function useBehaviorTracking(templateId) {
|
|
|
1731
1636
|
recommendations
|
|
1732
1637
|
};
|
|
1733
1638
|
}, [events]);
|
|
1734
|
-
const clear =
|
|
1639
|
+
const clear = useCallback6(() => {
|
|
1735
1640
|
setEvents([]);
|
|
1736
1641
|
setEventCount(0);
|
|
1737
1642
|
sessionStartRef.current = new Date;
|
|
@@ -1773,10 +1678,10 @@ function generateRecommendations(featuresUsed, unusedFeatures, mostUsedModes, to
|
|
|
1773
1678
|
}
|
|
1774
1679
|
|
|
1775
1680
|
// src/PersonalizationInsights.tsx
|
|
1776
|
-
import { useCallback as useCallback6, useMemo as useMemo6, useState as useState5 } from "react";
|
|
1777
1681
|
import { Button as Button4 } from "@contractspec/lib.design-system";
|
|
1778
|
-
import { Card as Card4 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
1779
1682
|
import { Badge as Badge4 } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
1683
|
+
import { Card as Card4 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
1684
|
+
import { useCallback as useCallback7, useMemo as useMemo6, useState as useState5 } from "react";
|
|
1780
1685
|
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1781
1686
|
"use client";
|
|
1782
1687
|
function PersonalizationInsights({
|
|
@@ -1787,7 +1692,7 @@ function PersonalizationInsights({
|
|
|
1787
1692
|
const { getSummary, eventCount, clear, sessionStart } = useBehaviorTracking(templateId);
|
|
1788
1693
|
const [showDetails, setShowDetails] = useState5(false);
|
|
1789
1694
|
const summary = useMemo6(() => getSummary(), [getSummary]);
|
|
1790
|
-
const formatDuration =
|
|
1695
|
+
const formatDuration = useCallback7((ms) => {
|
|
1791
1696
|
const seconds = Math.floor(ms / 1000);
|
|
1792
1697
|
const minutes = Math.floor(seconds / 60);
|
|
1793
1698
|
const hours = Math.floor(minutes / 60);
|
|
@@ -1799,7 +1704,7 @@ function PersonalizationInsights({
|
|
|
1799
1704
|
}
|
|
1800
1705
|
return `${seconds}s`;
|
|
1801
1706
|
}, []);
|
|
1802
|
-
const handleClear =
|
|
1707
|
+
const handleClear = useCallback7(() => {
|
|
1803
1708
|
clear();
|
|
1804
1709
|
}, [clear]);
|
|
1805
1710
|
if (collapsed) {
|
|
@@ -1825,7 +1730,7 @@ function PersonalizationInsights({
|
|
|
1825
1730
|
className: "overflow-hidden",
|
|
1826
1731
|
children: [
|
|
1827
1732
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
1828
|
-
className: "flex items-center justify-between border-
|
|
1733
|
+
className: "flex items-center justify-between border-blue-500/20 border-b bg-blue-500/5 px-4 py-3",
|
|
1829
1734
|
children: [
|
|
1830
1735
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
1831
1736
|
className: "flex items-center gap-2",
|
|
@@ -1850,7 +1755,7 @@ function PersonalizationInsights({
|
|
|
1850
1755
|
}, undefined, false, undefined, this),
|
|
1851
1756
|
onToggle && /* @__PURE__ */ jsxDEV6("button", {
|
|
1852
1757
|
onClick: onToggle,
|
|
1853
|
-
className: "text-muted-foreground hover:text-foreground
|
|
1758
|
+
className: "p-1 text-muted-foreground hover:text-foreground",
|
|
1854
1759
|
type: "button",
|
|
1855
1760
|
title: "Collapse",
|
|
1856
1761
|
children: "\u2715"
|
|
@@ -1892,7 +1797,7 @@ function PersonalizationInsights({
|
|
|
1892
1797
|
className: "mb-4",
|
|
1893
1798
|
children: [
|
|
1894
1799
|
/* @__PURE__ */ jsxDEV6("h4", {
|
|
1895
|
-
className: "mb-2
|
|
1800
|
+
className: "mb-2 font-semibold text-blue-400 text-xs uppercase",
|
|
1896
1801
|
children: "Recommendations"
|
|
1897
1802
|
}, undefined, false, undefined, this),
|
|
1898
1803
|
/* @__PURE__ */ jsxDEV6("ul", {
|
|
@@ -1916,7 +1821,7 @@ function PersonalizationInsights({
|
|
|
1916
1821
|
className: "mb-4",
|
|
1917
1822
|
children: [
|
|
1918
1823
|
/* @__PURE__ */ jsxDEV6("h4", {
|
|
1919
|
-
className: "mb-2
|
|
1824
|
+
className: "mb-2 font-semibold text-blue-400 text-xs uppercase",
|
|
1920
1825
|
children: "Try These Features"
|
|
1921
1826
|
}, undefined, false, undefined, this),
|
|
1922
1827
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
@@ -1933,7 +1838,7 @@ function PersonalizationInsights({
|
|
|
1933
1838
|
sessionStart
|
|
1934
1839
|
}, undefined, false, undefined, this),
|
|
1935
1840
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
1936
|
-
className: "mt-4 flex justify-end border-
|
|
1841
|
+
className: "mt-4 flex justify-end border-blue-500/10 border-t pt-4",
|
|
1937
1842
|
children: /* @__PURE__ */ jsxDEV6(Button4, {
|
|
1938
1843
|
variant: "ghost",
|
|
1939
1844
|
size: "sm",
|
|
@@ -1965,7 +1870,7 @@ function StatCard({
|
|
|
1965
1870
|
children: icon
|
|
1966
1871
|
}, undefined, false, undefined, this),
|
|
1967
1872
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
1968
|
-
className: "text-lg
|
|
1873
|
+
className: "font-bold text-lg",
|
|
1969
1874
|
children: value
|
|
1970
1875
|
}, undefined, false, undefined, this),
|
|
1971
1876
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
@@ -1980,12 +1885,12 @@ function DetailedInsights({
|
|
|
1980
1885
|
sessionStart
|
|
1981
1886
|
}) {
|
|
1982
1887
|
return /* @__PURE__ */ jsxDEV6("div", {
|
|
1983
|
-
className: "mt-4 space-y-4 border-
|
|
1888
|
+
className: "mt-4 space-y-4 border-blue-500/10 border-t pt-4",
|
|
1984
1889
|
children: [
|
|
1985
1890
|
summary.mostUsedTemplates.length > 0 && /* @__PURE__ */ jsxDEV6("div", {
|
|
1986
1891
|
children: [
|
|
1987
1892
|
/* @__PURE__ */ jsxDEV6("h4", {
|
|
1988
|
-
className: "mb-2
|
|
1893
|
+
className: "mb-2 font-semibold text-blue-400 text-xs uppercase",
|
|
1989
1894
|
children: "Most Used Templates"
|
|
1990
1895
|
}, undefined, false, undefined, this),
|
|
1991
1896
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
@@ -2011,7 +1916,7 @@ function DetailedInsights({
|
|
|
2011
1916
|
summary.mostUsedModes.length > 0 && /* @__PURE__ */ jsxDEV6("div", {
|
|
2012
1917
|
children: [
|
|
2013
1918
|
/* @__PURE__ */ jsxDEV6("h4", {
|
|
2014
|
-
className: "mb-2
|
|
1919
|
+
className: "mb-2 font-semibold text-blue-400 text-xs uppercase",
|
|
2015
1920
|
children: "Mode Usage"
|
|
2016
1921
|
}, undefined, false, undefined, this),
|
|
2017
1922
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
@@ -2037,7 +1942,7 @@ function DetailedInsights({
|
|
|
2037
1942
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
2038
1943
|
children: [
|
|
2039
1944
|
/* @__PURE__ */ jsxDEV6("h4", {
|
|
2040
|
-
className: "mb-2
|
|
1945
|
+
className: "mb-2 font-semibold text-blue-400 text-xs uppercase",
|
|
2041
1946
|
children: "Features Used"
|
|
2042
1947
|
}, undefined, false, undefined, this),
|
|
2043
1948
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
@@ -2071,8 +1976,8 @@ function formatTemplateId(id) {
|
|
|
2071
1976
|
}
|
|
2072
1977
|
|
|
2073
1978
|
// src/SaveToStudioButton.tsx
|
|
2074
|
-
import { useState as useState6 } from "react";
|
|
2075
1979
|
import { Sparkles } from "lucide-react";
|
|
1980
|
+
import { useState as useState6 } from "react";
|
|
2076
1981
|
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
2077
1982
|
"use client";
|
|
2078
1983
|
function SaveToStudioButton({
|
|
@@ -2122,7 +2027,7 @@ function SaveToStudioButton({
|
|
|
2122
2027
|
children: error
|
|
2123
2028
|
}, undefined, false, undefined, this) : null,
|
|
2124
2029
|
status === "saved" ? /* @__PURE__ */ jsxDEV7("p", {
|
|
2125
|
-
className: "text-
|
|
2030
|
+
className: "text-emerald-400 text-xs",
|
|
2126
2031
|
children: "Template sent to Studio."
|
|
2127
2032
|
}, undefined, false, undefined, this) : null
|
|
2128
2033
|
]
|
|
@@ -2146,7 +2051,7 @@ function SpecDrivenTemplateShell({
|
|
|
2146
2051
|
children
|
|
2147
2052
|
}) {
|
|
2148
2053
|
const headerContent = /* @__PURE__ */ jsxDEV8("header", {
|
|
2149
|
-
className: "border-border bg-card
|
|
2054
|
+
className: "rounded-2xl border border-border bg-card p-6 shadow-sm",
|
|
2150
2055
|
children: [
|
|
2151
2056
|
/* @__PURE__ */ jsxDEV8("div", {
|
|
2152
2057
|
className: "flex flex-wrap items-center justify-between gap-4",
|
|
@@ -2154,15 +2059,15 @@ function SpecDrivenTemplateShell({
|
|
|
2154
2059
|
/* @__PURE__ */ jsxDEV8("div", {
|
|
2155
2060
|
children: [
|
|
2156
2061
|
/* @__PURE__ */ jsxDEV8("p", {
|
|
2157
|
-
className: "text-muted-foreground text-sm
|
|
2062
|
+
className: "font-semibold text-muted-foreground text-sm uppercase tracking-wide",
|
|
2158
2063
|
children: "ContractSpec Templates"
|
|
2159
2064
|
}, undefined, false, undefined, this),
|
|
2160
2065
|
/* @__PURE__ */ jsxDEV8("h1", {
|
|
2161
|
-
className: "text-3xl
|
|
2066
|
+
className: "font-bold text-3xl",
|
|
2162
2067
|
children: title
|
|
2163
2068
|
}, undefined, false, undefined, this),
|
|
2164
2069
|
description ? /* @__PURE__ */ jsxDEV8("p", {
|
|
2165
|
-
className: "
|
|
2070
|
+
className: "mt-2 max-w-2xl text-muted-foreground text-sm",
|
|
2166
2071
|
children: description
|
|
2167
2072
|
}, undefined, false, undefined, this) : null
|
|
2168
2073
|
]
|
|
@@ -2193,7 +2098,7 @@ function SpecDrivenTemplateShell({
|
|
|
2193
2098
|
};
|
|
2194
2099
|
if (sidebar != null) {
|
|
2195
2100
|
slotContent.sidebar = /* @__PURE__ */ jsxDEV8("aside", {
|
|
2196
|
-
className: "border-border bg-card
|
|
2101
|
+
className: "rounded-2xl border border-border bg-card p-4",
|
|
2197
2102
|
children: sidebar
|
|
2198
2103
|
}, undefined, false, undefined, this);
|
|
2199
2104
|
}
|
|
@@ -2627,7 +2532,7 @@ contractSpec("${templateId}.main.v1", {
|
|
|
2627
2532
|
}
|
|
2628
2533
|
|
|
2629
2534
|
// src/hooks/useSpecContent.ts
|
|
2630
|
-
import { useCallback as
|
|
2535
|
+
import { useCallback as useCallback8, useEffect as useEffect4, useState as useState7 } from "react";
|
|
2631
2536
|
"use client";
|
|
2632
2537
|
var SPEC_STORAGE_KEY = "contractspec-spec-content";
|
|
2633
2538
|
function useSpecContent(templateId) {
|
|
@@ -2664,11 +2569,11 @@ function useSpecContent(templateId) {
|
|
|
2664
2569
|
}
|
|
2665
2570
|
setLoading(false);
|
|
2666
2571
|
}, [templateId]);
|
|
2667
|
-
const setContent =
|
|
2572
|
+
const setContent = useCallback8((newContent) => {
|
|
2668
2573
|
setContentState(newContent);
|
|
2669
2574
|
setValidation(null);
|
|
2670
2575
|
}, []);
|
|
2671
|
-
const save =
|
|
2576
|
+
const save = useCallback8(() => {
|
|
2672
2577
|
try {
|
|
2673
2578
|
const savedAt = new Date().toISOString();
|
|
2674
2579
|
localStorage.setItem(`${SPEC_STORAGE_KEY}-${templateId}`, JSON.stringify({
|
|
@@ -2679,7 +2584,7 @@ function useSpecContent(templateId) {
|
|
|
2679
2584
|
setLastSaved(savedAt);
|
|
2680
2585
|
} catch {}
|
|
2681
2586
|
}, [content, templateId]);
|
|
2682
|
-
const validate =
|
|
2587
|
+
const validate = useCallback8(() => {
|
|
2683
2588
|
const errors = [];
|
|
2684
2589
|
const lines = content.split(`
|
|
2685
2590
|
`);
|
|
@@ -2747,7 +2652,7 @@ function useSpecContent(templateId) {
|
|
|
2747
2652
|
setValidation(result);
|
|
2748
2653
|
return result;
|
|
2749
2654
|
}, [content]);
|
|
2750
|
-
const reset =
|
|
2655
|
+
const reset = useCallback8(() => {
|
|
2751
2656
|
const generated = generateSpecFromTemplate(template);
|
|
2752
2657
|
setContentState(generated);
|
|
2753
2658
|
setSavedContent(generated);
|
|
@@ -2771,9 +2676,9 @@ function useSpecContent(templateId) {
|
|
|
2771
2676
|
}
|
|
2772
2677
|
|
|
2773
2678
|
// src/SpecEditorPanel.tsx
|
|
2774
|
-
import { useCallback as useCallback8, useEffect as useEffect5 } from "react";
|
|
2775
2679
|
import { Button as Button5, LoaderBlock as LoaderBlock3 } from "@contractspec/lib.design-system";
|
|
2776
2680
|
import { Badge as Badge5 } from "@contractspec/lib.ui-kit-web/ui/badge";
|
|
2681
|
+
import { useCallback as useCallback9, useEffect as useEffect5 } from "react";
|
|
2777
2682
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
2778
2683
|
"use client";
|
|
2779
2684
|
function SpecEditorPanel({
|
|
@@ -2797,11 +2702,11 @@ function SpecEditorPanel({
|
|
|
2797
2702
|
onLog?.(`Spec loaded for ${templateId}`);
|
|
2798
2703
|
}
|
|
2799
2704
|
}, [loading, content, templateId, onLog]);
|
|
2800
|
-
const handleSave =
|
|
2705
|
+
const handleSave = useCallback9(() => {
|
|
2801
2706
|
save();
|
|
2802
2707
|
onLog?.("Spec saved locally");
|
|
2803
2708
|
}, [save, onLog]);
|
|
2804
|
-
const handleValidate =
|
|
2709
|
+
const handleValidate = useCallback9(() => {
|
|
2805
2710
|
const result = validate();
|
|
2806
2711
|
if (result.valid) {
|
|
2807
2712
|
onLog?.("Spec validation passed");
|
|
@@ -2811,7 +2716,7 @@ function SpecEditorPanel({
|
|
|
2811
2716
|
onLog?.(`Spec validation: ${errorCount} errors, ${warnCount} warnings`);
|
|
2812
2717
|
}
|
|
2813
2718
|
}, [validate, onLog]);
|
|
2814
|
-
const handleReset =
|
|
2719
|
+
const handleReset = useCallback9(() => {
|
|
2815
2720
|
reset();
|
|
2816
2721
|
onLog?.("Spec reset to template defaults");
|
|
2817
2722
|
}, [reset, onLog]);
|
|
@@ -2877,7 +2782,7 @@ function SpecEditorPanel({
|
|
|
2877
2782
|
className: "rounded-lg border border-amber-500/50 bg-amber-500/10 p-3",
|
|
2878
2783
|
children: [
|
|
2879
2784
|
/* @__PURE__ */ jsxDEV9("p", {
|
|
2880
|
-
className: "mb-2
|
|
2785
|
+
className: "mb-2 font-semibold text-amber-400 text-xs uppercase",
|
|
2881
2786
|
children: "Validation Issues"
|
|
2882
2787
|
}, undefined, false, undefined, this),
|
|
2883
2788
|
/* @__PURE__ */ jsxDEV9("ul", {
|
|
@@ -2895,7 +2800,7 @@ function SpecEditorPanel({
|
|
|
2895
2800
|
]
|
|
2896
2801
|
}, undefined, true, undefined, this),
|
|
2897
2802
|
/* @__PURE__ */ jsxDEV9("div", {
|
|
2898
|
-
className: "border-border bg-card
|
|
2803
|
+
className: "rounded-2xl border border-border bg-card p-4",
|
|
2899
2804
|
children: /* @__PURE__ */ jsxDEV9(SpecEditor, {
|
|
2900
2805
|
projectId: "sandbox",
|
|
2901
2806
|
type: "CAPABILITY",
|
|
@@ -2924,7 +2829,7 @@ var TemplateShell = ({
|
|
|
2924
2829
|
className: "space-y-6",
|
|
2925
2830
|
children: [
|
|
2926
2831
|
/* @__PURE__ */ jsxDEV10("header", {
|
|
2927
|
-
className: "border-border bg-card
|
|
2832
|
+
className: "rounded-2xl border border-border bg-card p-6 shadow-sm",
|
|
2928
2833
|
children: [
|
|
2929
2834
|
/* @__PURE__ */ jsxDEV10("div", {
|
|
2930
2835
|
className: "flex flex-wrap items-center justify-between gap-4",
|
|
@@ -2932,15 +2837,15 @@ var TemplateShell = ({
|
|
|
2932
2837
|
/* @__PURE__ */ jsxDEV10("div", {
|
|
2933
2838
|
children: [
|
|
2934
2839
|
/* @__PURE__ */ jsxDEV10("p", {
|
|
2935
|
-
className: "text-muted-foreground text-sm
|
|
2840
|
+
className: "font-semibold text-muted-foreground text-sm uppercase tracking-wide",
|
|
2936
2841
|
children: "ContractSpec Templates"
|
|
2937
2842
|
}, undefined, false, undefined, this),
|
|
2938
2843
|
/* @__PURE__ */ jsxDEV10("h1", {
|
|
2939
|
-
className: "text-3xl
|
|
2844
|
+
className: "font-bold text-3xl",
|
|
2940
2845
|
children: title
|
|
2941
2846
|
}, undefined, false, undefined, this),
|
|
2942
2847
|
description ? /* @__PURE__ */ jsxDEV10("p", {
|
|
2943
|
-
className: "
|
|
2848
|
+
className: "mt-2 max-w-2xl text-muted-foreground text-sm",
|
|
2944
2849
|
children: description
|
|
2945
2850
|
}, undefined, false, undefined, this) : null
|
|
2946
2851
|
]
|
|
@@ -2970,7 +2875,7 @@ var TemplateShell = ({
|
|
|
2970
2875
|
children
|
|
2971
2876
|
}, undefined, false, undefined, this),
|
|
2972
2877
|
sidebar ? /* @__PURE__ */ jsxDEV10("aside", {
|
|
2973
|
-
className: "border-border bg-card
|
|
2878
|
+
className: "rounded-2xl border border-border bg-card p-4",
|
|
2974
2879
|
children: sidebar
|
|
2975
2880
|
}, undefined, false, undefined, this) : null
|
|
2976
2881
|
]
|
|
@@ -2978,8 +2883,37 @@ var TemplateShell = ({
|
|
|
2978
2883
|
]
|
|
2979
2884
|
}, undefined, true, undefined, this);
|
|
2980
2885
|
|
|
2886
|
+
// src/hooks/useRegistryTemplates.ts
|
|
2887
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2888
|
+
function useRegistryTemplates() {
|
|
2889
|
+
return useQuery({
|
|
2890
|
+
queryKey: ["registryTemplates"],
|
|
2891
|
+
queryFn: async () => {
|
|
2892
|
+
const registryUrl = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL ?? "";
|
|
2893
|
+
if (!registryUrl)
|
|
2894
|
+
return [];
|
|
2895
|
+
const res = await fetch(`${registryUrl.replace(/\/$/, "")}/r/contractspec.json`, {
|
|
2896
|
+
method: "GET",
|
|
2897
|
+
headers: { Accept: "application/json" }
|
|
2898
|
+
});
|
|
2899
|
+
if (!res.ok)
|
|
2900
|
+
return [];
|
|
2901
|
+
const json = await res.json();
|
|
2902
|
+
const items = json.items ?? [];
|
|
2903
|
+
return items.filter((i) => i.type === "contractspec:template").map((i) => ({
|
|
2904
|
+
id: i.name,
|
|
2905
|
+
name: i.title ?? i.name,
|
|
2906
|
+
description: i.description,
|
|
2907
|
+
tags: i.meta?.tags ?? [],
|
|
2908
|
+
source: "registry",
|
|
2909
|
+
registryUrl
|
|
2910
|
+
}));
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2981
2915
|
// src/hooks/useWorkflowComposer.ts
|
|
2982
|
-
import { useCallback as
|
|
2916
|
+
import { useCallback as useCallback10, useEffect as useEffect6, useMemo as useMemo7, useState as useState8 } from "react";
|
|
2983
2917
|
"use client";
|
|
2984
2918
|
function useWorkflowComposer(templateId) {
|
|
2985
2919
|
const [selectedWorkflow, setSelectedWorkflow] = useState8(null);
|
|
@@ -2996,7 +2930,7 @@ function useWorkflowComposer(templateId) {
|
|
|
2996
2930
|
const currentBase = useMemo7(() => {
|
|
2997
2931
|
return baseWorkflows.find((w) => w.meta.key === selectedWorkflow) ?? null;
|
|
2998
2932
|
}, [baseWorkflows, selectedWorkflow]);
|
|
2999
|
-
const compose =
|
|
2933
|
+
const compose = useCallback10((scope) => {
|
|
3000
2934
|
if (!currentBase)
|
|
3001
2935
|
return null;
|
|
3002
2936
|
const applicableExtensions = extensions.filter((ext) => ext.workflow === currentBase.meta.key).filter((ext) => matchesScope(ext, scope)).sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
@@ -3010,13 +2944,13 @@ function useWorkflowComposer(templateId) {
|
|
|
3010
2944
|
return composedWorkflow;
|
|
3011
2945
|
}, [currentBase, extensions]);
|
|
3012
2946
|
const workflow = useMemo7(() => compose(), [compose]);
|
|
3013
|
-
const selectWorkflow =
|
|
2947
|
+
const selectWorkflow = useCallback10((workflowName) => {
|
|
3014
2948
|
setSelectedWorkflow(workflowName);
|
|
3015
2949
|
}, []);
|
|
3016
|
-
const addExtension =
|
|
2950
|
+
const addExtension = useCallback10((extension) => {
|
|
3017
2951
|
setExtensions((prev) => [...prev, extension]);
|
|
3018
2952
|
}, []);
|
|
3019
|
-
const removeExtension =
|
|
2953
|
+
const removeExtension = useCallback10((workflowName, index) => {
|
|
3020
2954
|
setExtensions((prev) => {
|
|
3021
2955
|
const forWorkflow = prev.filter((e) => e.workflow === workflowName);
|
|
3022
2956
|
const others = prev.filter((e) => e.workflow !== workflowName);
|
|
@@ -3024,7 +2958,7 @@ function useWorkflowComposer(templateId) {
|
|
|
3024
2958
|
return [...others, ...forWorkflow];
|
|
3025
2959
|
});
|
|
3026
2960
|
}, []);
|
|
3027
|
-
const generateSpecCode =
|
|
2961
|
+
const generateSpecCode = useCallback10(() => {
|
|
3028
2962
|
const composed = workflow;
|
|
3029
2963
|
if (!composed) {
|
|
3030
2964
|
return "// No workflow selected";
|
|
@@ -3468,47 +3402,8 @@ function getTemplateWorkflows(templateId) {
|
|
|
3468
3402
|
};
|
|
3469
3403
|
return templateWorkflows[templateId] ?? [];
|
|
3470
3404
|
}
|
|
3471
|
-
|
|
3472
|
-
// src/hooks/useRegistryTemplates.ts
|
|
3473
|
-
import { useQuery } from "@tanstack/react-query";
|
|
3474
|
-
function useRegistryTemplates() {
|
|
3475
|
-
return useQuery({
|
|
3476
|
-
queryKey: ["registryTemplates"],
|
|
3477
|
-
queryFn: async () => {
|
|
3478
|
-
const registryUrl = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL ?? "";
|
|
3479
|
-
if (!registryUrl)
|
|
3480
|
-
return [];
|
|
3481
|
-
const res = await fetch(`${registryUrl.replace(/\/$/, "")}/r/contractspec.json`, {
|
|
3482
|
-
method: "GET",
|
|
3483
|
-
headers: { Accept: "application/json" }
|
|
3484
|
-
});
|
|
3485
|
-
if (!res.ok)
|
|
3486
|
-
return [];
|
|
3487
|
-
const json = await res.json();
|
|
3488
|
-
const items = json.items ?? [];
|
|
3489
|
-
return items.filter((i) => i.type === "contractspec:template").map((i) => ({
|
|
3490
|
-
id: i.name,
|
|
3491
|
-
name: i.title ?? i.name,
|
|
3492
|
-
description: i.description,
|
|
3493
|
-
tags: i.meta?.tags ?? [],
|
|
3494
|
-
source: "registry",
|
|
3495
|
-
registryUrl
|
|
3496
|
-
}));
|
|
3497
|
-
}
|
|
3498
|
-
});
|
|
3499
|
-
}
|
|
3500
|
-
// src/utils/fetchPresentationData.ts
|
|
3501
|
-
async function fetchPresentationData(_presentationName, _templateId) {
|
|
3502
|
-
throw new Error("fetchPresentationData is deprecated. Use fetchData from TemplateRuntimeContext.");
|
|
3503
|
-
}
|
|
3504
|
-
function hasPresentationDataFetcher(_presentationName) {
|
|
3505
|
-
return false;
|
|
3506
|
-
}
|
|
3507
|
-
function getRegisteredPresentationFetchers() {
|
|
3508
|
-
return [];
|
|
3509
|
-
}
|
|
3510
3405
|
// src/lib/component-registry.tsx
|
|
3511
|
-
import {
|
|
3406
|
+
import { useEffect as useEffect7, useState as useState9 } from "react";
|
|
3512
3407
|
"use client";
|
|
3513
3408
|
|
|
3514
3409
|
class TemplateComponentRegistry {
|
|
@@ -3543,6 +3438,18 @@ function useTemplateComponents(templateId) {
|
|
|
3543
3438
|
}, [templateId]);
|
|
3544
3439
|
return components;
|
|
3545
3440
|
}
|
|
3441
|
+
// src/utils/fetchPresentationData.ts
|
|
3442
|
+
async function fetchPresentationData(_presentationName, _templateId) {
|
|
3443
|
+
throw new Error("fetchPresentationData is deprecated. Use fetchData from TemplateRuntimeContext.");
|
|
3444
|
+
}
|
|
3445
|
+
function hasPresentationDataFetcher(_presentationName) {
|
|
3446
|
+
return false;
|
|
3447
|
+
}
|
|
3448
|
+
function getRegisteredPresentationFetchers() {
|
|
3449
|
+
return [];
|
|
3450
|
+
}
|
|
3451
|
+
// src/index.ts
|
|
3452
|
+
import { MarkdownRenderer as MarkdownRenderer2 } from "@contractspec/lib.design-system";
|
|
3546
3453
|
export {
|
|
3547
3454
|
useWorkflowComposer,
|
|
3548
3455
|
useTemplateRuntime,
|
|
@@ -3568,7 +3475,7 @@ export {
|
|
|
3568
3475
|
PersonalizationInsights,
|
|
3569
3476
|
OverlayContextProvider,
|
|
3570
3477
|
MarkdownView,
|
|
3571
|
-
MarkdownRenderer,
|
|
3478
|
+
MarkdownRenderer2 as MarkdownRenderer,
|
|
3572
3479
|
LocalDataIndicator,
|
|
3573
3480
|
EvolutionSidebar,
|
|
3574
3481
|
EvolutionDashboard
|