@growthub/cli 0.13.8 → 0.14.0
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/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/codex-sites/route.js +13 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/env-status/route.js +31 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/apply/route.js +130 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceActivationPanel.jsx +17 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceHelperSetupModal.jsx +5 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ApiRegistryCreationCockpit.jsx +200 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/DataModelShell.jsx +501 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/HelperSidecar.jsx +75 -55
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/ReferencePicker.jsx +2 -2
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +215 -13
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apps/codex-sites-data-model-card.jsx +81 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apps/page.jsx +31 -14
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/settings/apps/settings-accordion-section.jsx +50 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workflows/WorkflowSurface.jsx +176 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +137 -5
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/adapters/integrations/resolver-loader.js +2 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/api-registry-creation-flow.js +317 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/api-response-profile.js +207 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/codex-sites-local-state.js +139 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/codex-sites-workspace-adapter.js +156 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/creation-error-recovery.js +103 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/env-status.js +100 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/orchestration-graph.js +63 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/sandbox-serverless-flow.js +215 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/server-resolver-write.js +67 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/serverless-upgrade.js +89 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-activation.js +11 -4
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +8 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper.js +7 -1
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-resolver-proposal.js +200 -0
- package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/package.json +1 -1
- package/package.json +1 -1
|
@@ -69,6 +69,7 @@ function ToolCallCard({ proposal, content, onOpenArtifact }) {
|
|
|
69
69
|
rationale: proposal?.rationale,
|
|
70
70
|
confidence: proposal?.confidence,
|
|
71
71
|
};
|
|
72
|
+
const showJson = meta.payload != null || meta.affectedField || meta.rationale;
|
|
72
73
|
return (
|
|
73
74
|
<div className="dm-helper-toolcall" data-toolcall-type={proposal?.type}>
|
|
74
75
|
<button
|
|
@@ -89,9 +90,11 @@ function ToolCallCard({ proposal, content, onOpenArtifact }) {
|
|
|
89
90
|
{open && (
|
|
90
91
|
<div className="dm-helper-toolcall-body">
|
|
91
92
|
{content && <div className="dm-helper-toolcall-content">{content}</div>}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
{showJson && (
|
|
94
|
+
<pre className="dm-helper-toolcall-json">
|
|
95
|
+
{JSON.stringify(meta, null, 2)}
|
|
96
|
+
</pre>
|
|
97
|
+
)}
|
|
95
98
|
</div>
|
|
96
99
|
)}
|
|
97
100
|
{canNavigate && (
|
|
@@ -108,6 +111,55 @@ function ToolCallCard({ proposal, content, onOpenArtifact }) {
|
|
|
108
111
|
);
|
|
109
112
|
}
|
|
110
113
|
|
|
114
|
+
function formatRunDuration(ms) {
|
|
115
|
+
const value = Number(ms);
|
|
116
|
+
if (!Number.isFinite(value) || value < 0) return "";
|
|
117
|
+
const totalSeconds = Math.max(0, Math.round(value / 1000));
|
|
118
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
119
|
+
const seconds = totalSeconds % 60;
|
|
120
|
+
if (minutes <= 0) return `${seconds}s`;
|
|
121
|
+
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function ProposalReviewCard({ proposal, checked, disabled, onCheckedChange, onKeyDown }) {
|
|
125
|
+
const [open, setOpen] = useState(false);
|
|
126
|
+
const summary = summarizePayload(proposal);
|
|
127
|
+
return (
|
|
128
|
+
<div className="dm-helper-toolcall" data-proposal-item="" tabIndex={0} onKeyDown={onKeyDown}>
|
|
129
|
+
<div className="dm-helper-toolcall-row dm-helper-proposal-card-row">
|
|
130
|
+
<input
|
|
131
|
+
type="checkbox"
|
|
132
|
+
checked={!!checked}
|
|
133
|
+
onChange={(e) => onCheckedChange(e.target.checked)}
|
|
134
|
+
disabled={disabled}
|
|
135
|
+
data-proposal-accept=""
|
|
136
|
+
aria-label={`Select ${proposal.type}`}
|
|
137
|
+
/>
|
|
138
|
+
<button
|
|
139
|
+
type="button"
|
|
140
|
+
className="dm-helper-proposal-card-toggle"
|
|
141
|
+
onClick={() => setOpen((v) => !v)}
|
|
142
|
+
aria-expanded={open}
|
|
143
|
+
>
|
|
144
|
+
<span className="dm-helper-toolcall-title">{proposal.type}</span>
|
|
145
|
+
<span className="dm-helper-proposal-field">→ {proposal.affectedField}</span>
|
|
146
|
+
<ChevronDown
|
|
147
|
+
size={14}
|
|
148
|
+
className={`dm-helper-toolcall-chevron${open ? " is-open" : ""}`}
|
|
149
|
+
aria-hidden="true"
|
|
150
|
+
/>
|
|
151
|
+
</button>
|
|
152
|
+
</div>
|
|
153
|
+
{open && (
|
|
154
|
+
<div className="dm-helper-toolcall-body">
|
|
155
|
+
{summary && <p className="dm-helper-proposal-payload" data-proposal-payload="">{summary}</p>}
|
|
156
|
+
{proposal.rationale && <p className="dm-helper-proposal-rationale">{proposal.rationale}</p>}
|
|
157
|
+
</div>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
111
163
|
// Pair a system apply-receipt message with the actual proposal payload
|
|
112
164
|
// it confirms. The applyResult (rehydrated from row.lastApplied at thread
|
|
113
165
|
// load time) carries the typed payloads keyed in order — we walk the
|
|
@@ -747,6 +799,11 @@ export function HelperSidecar({ open, onClose, workspaceConfig, initialIntent, i
|
|
|
747
799
|
const acceptedCount = Object.values(accepted).filter(Boolean).length;
|
|
748
800
|
const skippedCount = applyResult?.skipped?.length || 0;
|
|
749
801
|
const hasProposals = result && (result.proposals || []).length > 0;
|
|
802
|
+
const visibleWarnings = (result?.warnings || []).filter((warning) => {
|
|
803
|
+
const text = String(warning || "");
|
|
804
|
+
return !/transcript does not include the actual registry row id or lastResponse payload/i.test(text)
|
|
805
|
+
&& !/No credentials or env values should be stored/i.test(text);
|
|
806
|
+
});
|
|
750
807
|
|
|
751
808
|
// Thread is "active" the moment the user has sent at least one message,
|
|
752
809
|
// OR we have rehydrated a prior thread row. Pills only show on the
|
|
@@ -916,18 +973,9 @@ export function HelperSidecar({ open, onClose, workspaceConfig, initialIntent, i
|
|
|
916
973
|
{/* Proposals */}
|
|
917
974
|
{result && (
|
|
918
975
|
<div className="dm-helper-result">
|
|
919
|
-
|
|
920
|
-
<
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
{(result.warnings || []).length > 0 && (
|
|
924
|
-
<div className="dm-helper-warnings">
|
|
925
|
-
{result.warnings.map((w, i) => (
|
|
926
|
-
<div key={i} className="dm-helper-warning">
|
|
927
|
-
<AlertCircle size={12} />
|
|
928
|
-
<span>{w}</span>
|
|
929
|
-
</div>
|
|
930
|
-
))}
|
|
976
|
+
{!threadActive && result.summary && (
|
|
977
|
+
<div className="dm-helper-summary">
|
|
978
|
+
<span>{result.summary}</span>
|
|
931
979
|
</div>
|
|
932
980
|
)}
|
|
933
981
|
|
|
@@ -943,42 +991,17 @@ export function HelperSidecar({ open, onClose, workspaceConfig, initialIntent, i
|
|
|
943
991
|
aria-label="Proposals"
|
|
944
992
|
>
|
|
945
993
|
{result.proposals.map((proposal, i) => {
|
|
946
|
-
const summary = summarizePayload(proposal);
|
|
947
|
-
const conf = typeof proposal.confidence === "number" ? Math.round(proposal.confidence * 100) : null;
|
|
948
994
|
return (
|
|
949
|
-
<
|
|
995
|
+
<ProposalReviewCard
|
|
950
996
|
key={i}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
997
|
+
proposal={proposal}
|
|
998
|
+
checked={accepted[i]}
|
|
999
|
+
disabled={applying}
|
|
1000
|
+
onCheckedChange={(checked) =>
|
|
1001
|
+
setAccepted((prev) => ({ ...prev, [i]: checked }))
|
|
1002
|
+
}
|
|
954
1003
|
onKeyDown={(e) => handleProposalKeyDown(e, i)}
|
|
955
|
-
|
|
956
|
-
<input
|
|
957
|
-
type="checkbox"
|
|
958
|
-
checked={!!accepted[i]}
|
|
959
|
-
onChange={(e) =>
|
|
960
|
-
setAccepted((prev) => ({ ...prev, [i]: e.target.checked }))
|
|
961
|
-
}
|
|
962
|
-
disabled={applying}
|
|
963
|
-
data-proposal-accept=""
|
|
964
|
-
tabIndex={-1}
|
|
965
|
-
/>
|
|
966
|
-
<div className="dm-helper-proposal-body">
|
|
967
|
-
<div className="dm-helper-proposal-row">
|
|
968
|
-
<span className="dm-helper-proposal-type">{proposal.type}</span>
|
|
969
|
-
<span className="dm-helper-proposal-field">→ {proposal.affectedField}</span>
|
|
970
|
-
{conf !== null && (
|
|
971
|
-
<span className="dm-helper-proposal-confidence" data-proposal-confidence={conf}>
|
|
972
|
-
{conf}%
|
|
973
|
-
</span>
|
|
974
|
-
)}
|
|
975
|
-
</div>
|
|
976
|
-
{summary && (
|
|
977
|
-
<p className="dm-helper-proposal-payload" data-proposal-payload="">{summary}</p>
|
|
978
|
-
)}
|
|
979
|
-
<p className="dm-helper-proposal-rationale">{proposal.rationale}</p>
|
|
980
|
-
</div>
|
|
981
|
-
</label>
|
|
1004
|
+
/>
|
|
982
1005
|
);
|
|
983
1006
|
})}
|
|
984
1007
|
</div>
|
|
@@ -1055,13 +1078,10 @@ export function HelperSidecar({ open, onClose, workspaceConfig, initialIntent, i
|
|
|
1055
1078
|
)}
|
|
1056
1079
|
|
|
1057
1080
|
{result.receipts && (
|
|
1058
|
-
<
|
|
1059
|
-
|
|
1060
|
-
{
|
|
1061
|
-
|
|
1062
|
-
: "n/a"}{" "}
|
|
1063
|
-
· {result.receipts.latencyMs}ms
|
|
1064
|
-
</p>
|
|
1081
|
+
<div className="dm-helper-run-meta" data-helper-receipt="">
|
|
1082
|
+
<span>{result.receipts.model || "run"}</span>
|
|
1083
|
+
<span>{formatRunDuration(result.receipts.latencyMs)}</span>
|
|
1084
|
+
</div>
|
|
1065
1085
|
)}
|
|
1066
1086
|
</div>
|
|
1067
1087
|
)}
|
|
@@ -202,9 +202,9 @@ export function ReferencePicker({
|
|
|
202
202
|
<div className="dm-reference-picker">
|
|
203
203
|
{error && <p className="dm-field-error" style={{ fontSize: 11 }}>{error}</p>}
|
|
204
204
|
{showRepair && (
|
|
205
|
-
<p className="dm-
|
|
205
|
+
<p className="dm-reference-picker-warning">
|
|
206
206
|
<AlertTriangle size={12} aria-hidden />
|
|
207
|
-
<span>
|
|
207
|
+
<span>Missing reference. Pick a row or test the API Registry.</span>
|
|
208
208
|
</p>
|
|
209
209
|
)}
|
|
210
210
|
<SearchableSelect
|
package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css
CHANGED
|
@@ -857,7 +857,8 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
857
857
|
.workspace-dashboard-title {
|
|
858
858
|
min-width: 0;
|
|
859
859
|
}
|
|
860
|
-
.workspace-dashboard-title button
|
|
860
|
+
.workspace-dashboard-title button,
|
|
861
|
+
.workspace-dashboard-title a {
|
|
861
862
|
min-width: 0;
|
|
862
863
|
display: inline-flex;
|
|
863
864
|
align-items: center;
|
|
@@ -870,6 +871,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
870
871
|
overflow: hidden;
|
|
871
872
|
padding: 0;
|
|
872
873
|
text-align: left;
|
|
874
|
+
text-decoration: none;
|
|
873
875
|
text-overflow: ellipsis;
|
|
874
876
|
white-space: nowrap;
|
|
875
877
|
}
|
|
@@ -953,17 +955,24 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
953
955
|
background: #ffffff;
|
|
954
956
|
box-shadow: 0 12px 30px rgba(15, 23, 42, .16);
|
|
955
957
|
}
|
|
956
|
-
.workspace-row-action-menu button
|
|
958
|
+
.workspace-row-action-menu button,
|
|
959
|
+
.workspace-row-action-menu a {
|
|
957
960
|
width: 100%;
|
|
958
961
|
min-height: 30px;
|
|
962
|
+
display: inline-flex;
|
|
963
|
+
align-items: center;
|
|
959
964
|
justify-content: flex-start;
|
|
960
965
|
border: 0;
|
|
961
966
|
border-radius: 6px;
|
|
962
967
|
background: transparent;
|
|
963
968
|
color: #344054;
|
|
969
|
+
font: inherit;
|
|
970
|
+
font-size: 12px;
|
|
964
971
|
padding: 0 9px;
|
|
972
|
+
text-decoration: none;
|
|
965
973
|
}
|
|
966
|
-
.workspace-row-action-menu button:hover
|
|
974
|
+
.workspace-row-action-menu button:hover,
|
|
975
|
+
.workspace-row-action-menu a:hover {
|
|
967
976
|
background: #f5f5f5;
|
|
968
977
|
border-color: transparent;
|
|
969
978
|
}
|
|
@@ -3079,6 +3088,55 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
3079
3088
|
border-top: 1px solid #eeeeec;
|
|
3080
3089
|
padding: 20px 0;
|
|
3081
3090
|
}
|
|
3091
|
+
.workspace-settings-accordion {
|
|
3092
|
+
gap: 12px;
|
|
3093
|
+
}
|
|
3094
|
+
.workspace-settings-accordion-trigger {
|
|
3095
|
+
width: 100%;
|
|
3096
|
+
min-height: 34px;
|
|
3097
|
+
display: flex;
|
|
3098
|
+
align-items: center;
|
|
3099
|
+
justify-content: space-between;
|
|
3100
|
+
gap: 14px;
|
|
3101
|
+
border: 0;
|
|
3102
|
+
background: transparent;
|
|
3103
|
+
color: inherit;
|
|
3104
|
+
cursor: pointer;
|
|
3105
|
+
font: inherit;
|
|
3106
|
+
padding: 0;
|
|
3107
|
+
text-align: left;
|
|
3108
|
+
}
|
|
3109
|
+
.workspace-settings-accordion-trigger > span {
|
|
3110
|
+
min-width: 0;
|
|
3111
|
+
display: grid;
|
|
3112
|
+
gap: 3px;
|
|
3113
|
+
}
|
|
3114
|
+
.workspace-settings-accordion-trigger h3 {
|
|
3115
|
+
margin: 0;
|
|
3116
|
+
}
|
|
3117
|
+
.workspace-settings-accordion-trigger em {
|
|
3118
|
+
min-width: 0;
|
|
3119
|
+
display: block;
|
|
3120
|
+
color: #888;
|
|
3121
|
+
font-size: 12px;
|
|
3122
|
+
font-style: normal;
|
|
3123
|
+
overflow: hidden;
|
|
3124
|
+
text-overflow: ellipsis;
|
|
3125
|
+
white-space: nowrap;
|
|
3126
|
+
}
|
|
3127
|
+
.workspace-settings-accordion-trigger svg {
|
|
3128
|
+
flex: 0 0 auto;
|
|
3129
|
+
color: #777;
|
|
3130
|
+
transition: transform .16s ease;
|
|
3131
|
+
}
|
|
3132
|
+
.workspace-settings-accordion.is-open .workspace-settings-accordion-trigger svg {
|
|
3133
|
+
transform: rotate(180deg);
|
|
3134
|
+
}
|
|
3135
|
+
.workspace-settings-accordion-body {
|
|
3136
|
+
min-height: 0;
|
|
3137
|
+
display: grid;
|
|
3138
|
+
gap: 12px;
|
|
3139
|
+
}
|
|
3082
3140
|
.workspace-apps-linkage-section {
|
|
3083
3141
|
flex: 0 0 auto;
|
|
3084
3142
|
padding-bottom: 16px;
|
|
@@ -3089,6 +3147,9 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
3089
3147
|
grid-template-rows: auto minmax(0, 1fr);
|
|
3090
3148
|
padding-bottom: 0;
|
|
3091
3149
|
}
|
|
3150
|
+
.workspace-apps-list-section .workspace-settings-accordion-body {
|
|
3151
|
+
min-height: 0;
|
|
3152
|
+
}
|
|
3092
3153
|
.workspace-settings-section:first-of-type {
|
|
3093
3154
|
border-top: 0;
|
|
3094
3155
|
padding-top: 0;
|
|
@@ -3577,6 +3638,52 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
3577
3638
|
font-size: 12px;
|
|
3578
3639
|
line-height: 1.4;
|
|
3579
3640
|
}
|
|
3641
|
+
.workspace-settings-action {
|
|
3642
|
+
min-height: 32px;
|
|
3643
|
+
display: inline-flex;
|
|
3644
|
+
align-items: center;
|
|
3645
|
+
gap: 6px;
|
|
3646
|
+
border: 1px solid #dedede;
|
|
3647
|
+
border-radius: 6px;
|
|
3648
|
+
background: #fff;
|
|
3649
|
+
color: #333;
|
|
3650
|
+
font: inherit;
|
|
3651
|
+
font-size: 12px;
|
|
3652
|
+
padding: 0 10px;
|
|
3653
|
+
}
|
|
3654
|
+
.workspace-settings-codex-sites-list {
|
|
3655
|
+
display: grid;
|
|
3656
|
+
gap: 6px;
|
|
3657
|
+
padding: 0 14px 0;
|
|
3658
|
+
}
|
|
3659
|
+
.workspace-settings-codex-sites-list a,
|
|
3660
|
+
.workspace-settings-codex-sites-list button {
|
|
3661
|
+
min-height: 34px;
|
|
3662
|
+
display: grid;
|
|
3663
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, .8fr) auto;
|
|
3664
|
+
gap: 10px;
|
|
3665
|
+
align-items: center;
|
|
3666
|
+
border: 1px solid #ececea;
|
|
3667
|
+
border-radius: 6px;
|
|
3668
|
+
background: #fff;
|
|
3669
|
+
color: #333;
|
|
3670
|
+
font: inherit;
|
|
3671
|
+
font-size: 12px;
|
|
3672
|
+
text-align: left;
|
|
3673
|
+
text-decoration: none;
|
|
3674
|
+
padding: 0 10px;
|
|
3675
|
+
}
|
|
3676
|
+
.workspace-settings-codex-sites-list span,
|
|
3677
|
+
.workspace-settings-codex-sites-list em {
|
|
3678
|
+
min-width: 0;
|
|
3679
|
+
overflow: hidden;
|
|
3680
|
+
text-overflow: ellipsis;
|
|
3681
|
+
white-space: nowrap;
|
|
3682
|
+
}
|
|
3683
|
+
.workspace-settings-codex-sites-list em {
|
|
3684
|
+
color: #777;
|
|
3685
|
+
font-style: normal;
|
|
3686
|
+
}
|
|
3580
3687
|
|
|
3581
3688
|
/* Source picker */
|
|
3582
3689
|
.workspace-source-list {
|
|
@@ -4639,7 +4746,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4639
4746
|
.dm-detail-v2-title h2 { margin: 0; font-size: 15px; font-weight: 600; color: #111827; flex: 1; }
|
|
4640
4747
|
.dm-detail-v2-meta { display: flex; align-items: center; gap: 10px; padding-left: 21px; font-size: 12px; color: #9ca3af; }
|
|
4641
4748
|
.dm-detail-v2-meta code { font-size: 11px; color: #6b7280; background: #f3f4f6; border-radius: 4px; padding: 2px 6px; }
|
|
4642
|
-
.dm-detail-v3 { border: 1px solid #e5e7eb; border-radius: 12px; background: #fff; overflow:
|
|
4749
|
+
.dm-detail-v3 { border: 1px solid #e5e7eb; border-radius: 12px; background: #fff; overflow: visible; }
|
|
4643
4750
|
.dm-picker { position: relative; min-width: 280px; }
|
|
4644
4751
|
.dm-picker-trigger { width: min(420px, 100%); display: inline-flex; align-items: center; gap: 10px; min-height: 40px; border: 1px solid #dbe2ea; border-radius: 10px; background: #fff; color: #0f172a; box-shadow: 0 1px 2px rgba(15,23,42,.05); font: inherit; padding: 0 12px; cursor: pointer; text-align: left; }
|
|
4645
4752
|
.dm-picker.open .dm-picker-trigger { border-color: #94a3b8; box-shadow: 0 0 0 4px rgba(148,163,184,.14); }
|
|
@@ -4680,6 +4787,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4680
4787
|
.workspace-toolbar-actions .dm-picker-popover {
|
|
4681
4788
|
left: auto;
|
|
4682
4789
|
right: 0;
|
|
4790
|
+
z-index: 220;
|
|
4683
4791
|
}
|
|
4684
4792
|
|
|
4685
4793
|
/* Active-object title block in the workspace toolbar — replaces the
|
|
@@ -4729,13 +4837,13 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4729
4837
|
font-weight: 400;
|
|
4730
4838
|
color: #6b7280;
|
|
4731
4839
|
}
|
|
4732
|
-
.dm-picker-popover { position: absolute; top: calc(100% + 8px); left: 0; z-index:
|
|
4840
|
+
.dm-picker-popover { position: absolute; top: calc(100% + 8px); left: 0; z-index: 220; width: min(360px, calc(100vw - 32px)); max-height: min(520px, calc(100vh - 120px)); display: grid; gap: 10px; padding: 12px; border: 1px solid #dbe2ea; border-radius: 14px; background: #fff; box-shadow: 0 28px 80px rgba(15,23,42,.24); overflow-y: auto; overflow-x: visible; }
|
|
4733
4841
|
.dm-picker-tabs { display: inline-flex; gap: 6px; padding: 4px; border-radius: 999px; background: #f8fafc; }
|
|
4734
4842
|
.dm-picker-tabs button { height: 28px; border: 0; border-radius: 999px; background: transparent; color: #64748b; font: inherit; font-size: 12px; padding: 0 10px; cursor: pointer; }
|
|
4735
4843
|
.dm-picker-tabs button.active { background: #fff; color: #111827; box-shadow: 0 1px 2px rgba(15,23,42,.08); }
|
|
4736
4844
|
.dm-picker-section { display: grid; gap: 8px; }
|
|
4737
4845
|
.dm-picker-section > p { margin: 0; font-size: 11px; font-weight: 700; color: #94a3b8; text-transform: uppercase; letter-spacing: .06em; }
|
|
4738
|
-
.dm-picker-scroll { display: grid; gap: 4px; max-height:
|
|
4846
|
+
.dm-picker-scroll { display: grid; gap: 4px; max-height: none; overflow: visible; padding-right: 10px; scrollbar-gutter: stable; }
|
|
4739
4847
|
.dm-picker-item { position: relative; display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 8px; align-items: center; }
|
|
4740
4848
|
.dm-picker-row { width: 100%; display: inline-flex; align-items: center; gap: 8px; min-width: 0; min-height: 34px; border: 0; border-radius: 9px; background: transparent; color: #334155; font: inherit; font-size: 12px; font-weight: 500; padding: 0 10px; cursor: pointer; text-align: left; }
|
|
4741
4849
|
.dm-picker-row:hover, .dm-picker-item.active .dm-picker-row { background: #f1f5f9; color: #111827; }
|
|
@@ -4746,7 +4854,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4746
4854
|
.dm-picker-icon-btn:hover { color: #111827; border-color: #cbd5e1; }
|
|
4747
4855
|
.dm-picker-icon-btn.danger:hover { color: #b91c1c; border-color: #fecaca; background: #fef2f2; }
|
|
4748
4856
|
.dm-picker-lock { margin-left: auto; color: #94a3b8; }
|
|
4749
|
-
.dm-picker-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index:
|
|
4857
|
+
.dm-picker-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 240; display: grid; gap: 4px; min-width: 156px; padding: 8px; border: 1px solid #dbe2ea; border-radius: 10px; background: #fff; box-shadow: 0 20px 44px rgba(15,23,42,.2), 0 4px 12px rgba(15,23,42,.08); }
|
|
4750
4858
|
.dm-picker-menu button { display: inline-flex; align-items: center; gap: 8px; height: 30px; border: 0; border-radius: 7px; background: transparent; color: #334155; font: inherit; font-size: 12px; padding: 0 10px; cursor: pointer; text-align: left; }
|
|
4751
4859
|
.dm-picker-menu button:hover { background: #f1f5f9; color: #111827; }
|
|
4752
4860
|
.dm-picker-menu button.danger:hover { background: #fef2f2; color: #b91c1c; }
|
|
@@ -4922,7 +5030,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4922
5030
|
.dm-db-status.warn { border-color: #fde68a; background: #fffbeb; color: #92400e; }
|
|
4923
5031
|
.dm-db-status.warn span { background: #f59e0b; }
|
|
4924
5032
|
.dm-record-backdrop { position: fixed; inset: 0; z-index: 80; background: rgba(15,23,42,.12); }
|
|
4925
|
-
.dm-record-drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 81; display: flex; flex-direction: column; width: min(440px, 100vw); background: #fff; border-left: 1px solid #dfe3e8; box-shadow: -10px 0 34px rgba(15,23,42,.16); }
|
|
5033
|
+
.dm-record-drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 81; display: flex; flex-direction: column; min-height: 0; width: min(440px, 100vw); background: #fff; border-left: 1px solid #dfe3e8; box-shadow: -10px 0 34px rgba(15,23,42,.16); overflow: hidden; }
|
|
4926
5034
|
.dm-record-drawer-wide { width: min(780px, 100vw); }
|
|
4927
5035
|
.dm-api-action-card {
|
|
4928
5036
|
display: grid;
|
|
@@ -4962,6 +5070,59 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
4962
5070
|
.dm-api-action-card-body h3 { margin: 0; font-size: 14px; font-weight: 650; color: #111827; }
|
|
4963
5071
|
.dm-api-action-card-body p { margin: 0; font-size: 12px; line-height: 1.45; color: #4b5563; }
|
|
4964
5072
|
.dm-api-action-card-cta { flex-shrink: 0; align-self: center; }
|
|
5073
|
+
|
|
5074
|
+
/* Governed creation cockpit — vertical journey inside the api-registry drawer.
|
|
5075
|
+
Overrides the action-card 3-col grid and reuses the workspace's own status
|
|
5076
|
+
chip (.dm-db-status) + dm-btn-* buttons. No new colors, no new primitive. */
|
|
5077
|
+
.dm-cockpit { display: block; grid-template-columns: none; transition: box-shadow .14s, background .14s; }
|
|
5078
|
+
.dm-cockpit.is-collapsed { padding-bottom: 12px; }
|
|
5079
|
+
.dm-cockpit-head { width: 100%; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; border: 0; background: transparent; padding: 0; text-align: left; cursor: pointer; }
|
|
5080
|
+
.dm-cockpit-head:hover .dm-api-action-card-body h3 { color: #000; }
|
|
5081
|
+
.dm-cockpit-head:focus-visible { outline: 2px solid #bfdbfe; outline-offset: 4px; border-radius: 6px; }
|
|
5082
|
+
.dm-cockpit-count { flex-shrink: 0; font-size: 11px; font-weight: 700; color: #94a3b8; font-variant-numeric: tabular-nums; padding-top: 2px; }
|
|
5083
|
+
.dm-cockpit-steps { list-style: none; margin: 10px 0 0; padding: 0; }
|
|
5084
|
+
.dm-cockpit-step { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: start; padding: 10px 0; border-top: 1px solid #edf0f3; }
|
|
5085
|
+
.dm-cockpit-step:first-child { border-top: 0; }
|
|
5086
|
+
.dm-cockpit-step-chip { flex-shrink: 0; align-self: start; margin-top: 1px; min-width: 64px; justify-content: center; }
|
|
5087
|
+
.dm-cockpit-step-body { min-width: 0; display: grid; gap: 2px; }
|
|
5088
|
+
.dm-cockpit-step-label { margin: 0; font-size: 13px; font-weight: 600; color: #111827; }
|
|
5089
|
+
.dm-cockpit-step-desc { margin: 0; font-size: 12px; line-height: 1.45; color: #64748b; }
|
|
5090
|
+
.dm-cockpit-step-hint { margin: 0; font-size: 11px; line-height: 1.4; color: #94a3b8; }
|
|
5091
|
+
.dm-cockpit-step button { flex-shrink: 0; align-self: center; }
|
|
5092
|
+
.dm-cockpit-step-muted .dm-cockpit-step-label,
|
|
5093
|
+
.dm-cockpit-step-muted .dm-cockpit-step-desc { color: #94a3b8; }
|
|
5094
|
+
.dm-cockpit-step-next { background: #f8fafc; margin: 0 -14px; padding-left: 14px; padding-right: 14px; border-radius: 6px; }
|
|
5095
|
+
.dm-cockpit-shape { margin-top: 12px; padding-top: 12px; border-top: 1px solid #edf0f3; display: grid; gap: 6px; }
|
|
5096
|
+
.dm-cockpit-shape-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
5097
|
+
.dm-cockpit-shape-head .dm-api-action-card-eyebrow { margin: 0; }
|
|
5098
|
+
.dm-cockpit-fields { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
|
|
5099
|
+
.dm-cockpit-field { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: #475569; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; padding: 2px 8px; }
|
|
5100
|
+
.dm-cockpit-field b { font-weight: 700; color: #94a3b8; text-transform: uppercase; font-size: 10px; letter-spacing: .03em; }
|
|
5101
|
+
.dm-cockpit-receipts { margin-top: 12px; padding-top: 12px; border-top: 1px solid #edf0f3; }
|
|
5102
|
+
.dm-cockpit-receipts ul { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 6px; }
|
|
5103
|
+
.dm-cockpit-receipt { display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: start; }
|
|
5104
|
+
.dm-cockpit-receipt-chip { align-self: start; }
|
|
5105
|
+
.dm-cockpit-receipt-text { font-size: 12px; color: #64748b; line-height: 1.4; }
|
|
5106
|
+
|
|
5107
|
+
/* Serverless upgrade — toolbar button, one-time nudge, and cockpit panel. */
|
|
5108
|
+
.dm-workflow-upgrade-btn { position: relative; }
|
|
5109
|
+
.dm-workflow-upgrade-btn.is-serverless { color: #166534; }
|
|
5110
|
+
.dm-workflow-upgrade-btn.is-pulse { color: #111827; }
|
|
5111
|
+
.dm-workflow-upgrade-btn[data-tooltip]:hover::after {
|
|
5112
|
+
content: attr(data-tooltip); position: absolute; top: 100%; right: 0; margin-top: 6px;
|
|
5113
|
+
white-space: nowrap; background: #111827; color: #fff; font-size: 11px; font-weight: 500;
|
|
5114
|
+
padding: 5px 8px; border-radius: 6px; z-index: 40; box-shadow: 0 4px 12px rgba(15,23,42,.18);
|
|
5115
|
+
}
|
|
5116
|
+
.dm-workflow-upgrade-nudge { align-items: center; justify-content: space-between; gap: 16px; padding: 10px 16px; }
|
|
5117
|
+
.dm-workflow-upgrade-nudge > div:first-child { min-width: 0; padding-right: 10px; }
|
|
5118
|
+
.dm-workflow-upgrade-nudge strong,
|
|
5119
|
+
.dm-workflow-upgrade-nudge span { line-height: 1.35; }
|
|
5120
|
+
.dm-workflow-upgrade-nudge-actions { display: inline-flex; align-items: center; gap: 8px; }
|
|
5121
|
+
.dm-workflow-upgrade-panel { width: auto; margin: 12px 8px 16px; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; box-shadow: 0 2px 8px rgba(15,23,42,.06); }
|
|
5122
|
+
.dm-workflow-upgrade-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px 0; }
|
|
5123
|
+
.dm-workflow-upgrade-panel-head .dm-api-action-card-eyebrow { margin: 0; }
|
|
5124
|
+
.dm-workflow-upgrade-panel .dm-api-action-card { margin: 8px; box-shadow: none; }
|
|
5125
|
+
|
|
4965
5126
|
.dm-api-review-banner {
|
|
4966
5127
|
display: grid;
|
|
4967
5128
|
grid-template-columns: auto 1fr auto;
|
|
@@ -5115,6 +5276,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5115
5276
|
display: flex;
|
|
5116
5277
|
align-items: center;
|
|
5117
5278
|
gap: 6px;
|
|
5279
|
+
padding-left: 16px;
|
|
5118
5280
|
min-width: max-content;
|
|
5119
5281
|
flex: 1 0 auto;
|
|
5120
5282
|
color: #8b8b91;
|
|
@@ -5168,6 +5330,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5168
5330
|
display: flex;
|
|
5169
5331
|
align-items: center;
|
|
5170
5332
|
gap: 6px;
|
|
5333
|
+
padding-right: 16px;
|
|
5171
5334
|
flex: 0 1 auto;
|
|
5172
5335
|
min-width: 0;
|
|
5173
5336
|
max-width: 58vw;
|
|
@@ -5917,6 +6080,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
5917
6080
|
.dm-drawer-hidden-list { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
5918
6081
|
.dm-record-drawer-head p { margin: 0 0 3px; color: #94a3b8; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
|
|
5919
6082
|
.dm-record-drawer-head h2 { margin: 0; color: #111827; font-size: 16px; font-weight: 650; }
|
|
6083
|
+
.dm-record-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-gutter: stable; padding: 0 0 28px; }
|
|
5920
6084
|
.dm-record-testbar { display: flex; align-items: center; gap: 8px; padding: 10px 18px; border-bottom: 1px solid #edf0f3; background: #fbfdff; }
|
|
5921
6085
|
.dm-record-testbar > span:last-child { min-width: 0; color: #64748b; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
5922
6086
|
.dm-record-testbar[data-panel="sandbox-agent-auth"] {
|
|
@@ -6006,7 +6170,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
6006
6170
|
white-space: pre-wrap;
|
|
6007
6171
|
word-break: break-word;
|
|
6008
6172
|
}
|
|
6009
|
-
.dm-record-fields { display: grid; gap: 8px; padding: 14px 16px
|
|
6173
|
+
.dm-record-fields { display: grid; align-content: start; gap: 8px; min-height: 0; padding: 14px 16px 0; }
|
|
6010
6174
|
.dm-record-field { display: grid; gap: 5px; }
|
|
6011
6175
|
.dm-record-field span { color: #475569; font-size: 11px; font-weight: 650; }
|
|
6012
6176
|
.dm-record-field input,
|
|
@@ -6029,7 +6193,7 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
6029
6193
|
.dm-radio-row input[type="radio"], .dm-check-row input[type="checkbox"] { width: 14px; height: 14px; margin: 1px 0 0; padding: 0; box-shadow: none; accent-color: #111827; }
|
|
6030
6194
|
.dm-radio-row span, .dm-check-row span { color: #1f2937; font-size: 12px; font-weight: 500; }
|
|
6031
6195
|
.dm-check-row { cursor: pointer; }
|
|
6032
|
-
.dm-select { position: relative; width: 100%; min-width:
|
|
6196
|
+
.dm-select { position: relative; width: 100%; min-width: 0; font-size: 11px; }
|
|
6033
6197
|
.dm-select-trigger { width: 100%; min-height: 32px; display: flex; align-items: center; justify-content: space-between; gap: 8px; border: 1px solid #cbd5e1; border-radius: 7px; background: #fff; color: #111827; box-shadow: 0 1px 2px rgba(15,23,42,.05); font: inherit; font-size: 11px; padding: 6px 10px; text-align: left; cursor: pointer; transition: border-color .12s, box-shadow .12s, background .12s; }
|
|
6034
6198
|
.dm-select-trigger:hover:not(:disabled) { border-color: #94a3b8; box-shadow: 0 2px 8px rgba(15,23,42,.08); }
|
|
6035
6199
|
.dm-select.open .dm-select-trigger { border-color: #64748b; box-shadow: 0 0 0 3px rgba(100,116,139,.12), 0 2px 8px rgba(15,23,42,.08); }
|
|
@@ -6054,8 +6218,12 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
6054
6218
|
.dm-select-pager button { height: 26px; border: 1px solid #e2e8f0; border-radius: 6px; background: #fff; color: #334155; font: inherit; font-size: 12px; padding: 0 8px; cursor: pointer; }
|
|
6055
6219
|
.dm-select-pager button:disabled { opacity: .45; cursor: not-allowed; }
|
|
6056
6220
|
.dm-select-pager span { color: #64748b; font-size: 12px; font-weight: 650; }
|
|
6057
|
-
.dm-
|
|
6058
|
-
.dm-
|
|
6221
|
+
.dm-reference-picker { display: grid; gap: 6px; width: min(240px, 100%); min-width: 0; }
|
|
6222
|
+
.dm-reference-picker-warning { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; margin: 0; padding: 5px 7px; border: 1px solid #fde68a; border-radius: 6px; background: #fffbeb; color: #92400e; font-size: 11px; line-height: 1.25; }
|
|
6223
|
+
.dm-reference-picker-warning svg { flex: 0 0 auto; }
|
|
6224
|
+
.dm-reference-picker-warning span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
6225
|
+
.dm-db-grid td:has(.dm-select) { overflow: visible; padding-top: 5px; padding-bottom: 5px; vertical-align: top; }
|
|
6226
|
+
.dm-db-grid td .dm-select { min-width: 0; }
|
|
6059
6227
|
.dm-json-field { position: relative; }
|
|
6060
6228
|
.dm-json-field > span { padding-right: 34px; }
|
|
6061
6229
|
.dm-json-expand { position: absolute; top: 0; right: 0; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 24px; border: 1px solid #e2e8f0; border-radius: 6px; background: #fff; color: #64748b; box-shadow: 0 1px 2px rgba(15,23,42,.05); opacity: 0; cursor: pointer; transition: opacity .12s, border-color .12s, color .12s, box-shadow .12s; }
|
|
@@ -6499,6 +6667,40 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
|
|
|
6499
6667
|
background: #f5f5f5;
|
|
6500
6668
|
border-color: #9ca3af;
|
|
6501
6669
|
}
|
|
6670
|
+
.dm-helper-run-meta {
|
|
6671
|
+
display: flex;
|
|
6672
|
+
align-items: center;
|
|
6673
|
+
justify-content: space-between;
|
|
6674
|
+
gap: 12px;
|
|
6675
|
+
padding-top: 8px;
|
|
6676
|
+
border-top: 1px solid #e5e7eb;
|
|
6677
|
+
color: #6b7280;
|
|
6678
|
+
font-size: 12px;
|
|
6679
|
+
line-height: 1.3;
|
|
6680
|
+
}
|
|
6681
|
+
.dm-helper-proposal-card-row {
|
|
6682
|
+
grid-template-columns: 18px 1fr;
|
|
6683
|
+
}
|
|
6684
|
+
.dm-helper-proposal-card-row input[type=checkbox] {
|
|
6685
|
+
width: 14px;
|
|
6686
|
+
height: 14px;
|
|
6687
|
+
margin: 0;
|
|
6688
|
+
accent-color: #111827;
|
|
6689
|
+
}
|
|
6690
|
+
.dm-helper-proposal-card-toggle {
|
|
6691
|
+
display: grid;
|
|
6692
|
+
grid-template-columns: minmax(0, max-content) minmax(0, 1fr) auto;
|
|
6693
|
+
align-items: center;
|
|
6694
|
+
gap: 6px;
|
|
6695
|
+
width: 100%;
|
|
6696
|
+
padding: 0;
|
|
6697
|
+
border: 0;
|
|
6698
|
+
background: transparent;
|
|
6699
|
+
color: inherit;
|
|
6700
|
+
font: inherit;
|
|
6701
|
+
text-align: left;
|
|
6702
|
+
cursor: pointer;
|
|
6703
|
+
}
|
|
6502
6704
|
|
|
6503
6705
|
.dm-helper-typing {
|
|
6504
6706
|
display: inline-flex;
|
|
@@ -8852,7 +9054,7 @@ body.workspace-rail-collapsed .workspace-builder.workspace-lens-page,
|
|
|
8852
9054
|
.workspace-lens-helper-callout-btn { flex-shrink: 0; font-size: 12px; font-weight: 600; color: #111827; background: #ffffff; border: 1px solid #d1d5db; border-radius: 6px; padding: 7px 12px; cursor: pointer; }
|
|
8853
9055
|
.workspace-lens-helper-callout-btn:hover:not(:disabled) { background: #f3f4f6; }
|
|
8854
9056
|
.workspace-lens-helper-callout-btn:disabled { opacity: 0.6; cursor: default; }
|
|
8855
|
-
.workspace-helper-setup-modal-backdrop { position: fixed; inset: 0; z-index:
|
|
9057
|
+
.workspace-helper-setup-modal-backdrop { position: fixed; inset: 0; z-index: 5100; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(17, 24, 39, 0.42); backdrop-filter: blur(3px); }
|
|
8856
9058
|
.workspace-helper-setup-modal { position: relative; width: min(620px, 100%); max-height: min(720px, calc(100vh - 48px)); overflow: auto; background: #ffffff; border: 1px solid #d1d5db; border-radius: 8px; box-shadow: 0 24px 70px rgba(17, 24, 39, 0.28); padding: 18px; }
|
|
8857
9059
|
.workspace-helper-setup-modal-close { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff; color: #6b7280; cursor: pointer; }
|
|
8858
9060
|
.workspace-helper-setup-modal-close:hover { background: #f9fafb; color: #111827; }
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ExternalLink, Rocket } from "lucide-react";
|
|
4
|
+
import {
|
|
5
|
+
CODEX_SITES_OBJECT_ID,
|
|
6
|
+
ensureCodexSitesDataModel,
|
|
7
|
+
isCodexSiteUrl
|
|
8
|
+
} from "@/lib/codex-sites-workspace-adapter";
|
|
9
|
+
import { SettingsAccordionSection } from "./settings-accordion-section.jsx";
|
|
10
|
+
|
|
11
|
+
function CodexSitesDataModelCard({ apps, dataModel }) {
|
|
12
|
+
const objects = Array.isArray(dataModel?.objects) ? dataModel.objects : [];
|
|
13
|
+
const object = objects.find((item) => item?.id === CODEX_SITES_OBJECT_ID) || null;
|
|
14
|
+
const rows = Array.isArray(object?.rows) ? object.rows : [];
|
|
15
|
+
const liveRows = rows.filter((row) => {
|
|
16
|
+
const status = String(row?.status || "").toLowerCase();
|
|
17
|
+
return isCodexSiteUrl(row?.url) && (status === "live" || status === "active");
|
|
18
|
+
});
|
|
19
|
+
const liveCount = liveRows.length;
|
|
20
|
+
const appCount = new Set(rows.map((row) => row?.app).filter(Boolean)).size;
|
|
21
|
+
|
|
22
|
+
async function openDataModel() {
|
|
23
|
+
if (!object) {
|
|
24
|
+
const nextDataModel = ensureCodexSitesDataModel(dataModel, apps);
|
|
25
|
+
const response = await fetch("/api/workspace", {
|
|
26
|
+
method: "PATCH",
|
|
27
|
+
headers: { "content-type": "application/json" },
|
|
28
|
+
body: JSON.stringify({ dataModel: nextDataModel })
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const payload = await response.json().catch(() => ({}));
|
|
32
|
+
window.alert(payload.error || "Failed to create Codex Sites object.");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
window.location.href = `/data-model?object=${encodeURIComponent(CODEX_SITES_OBJECT_ID)}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return <SettingsAccordionSection
|
|
40
|
+
id="codex-sites"
|
|
41
|
+
title="Codex Sites"
|
|
42
|
+
summary={`${rows.length} site${rows.length === 1 ? "" : "s"} · ${liveCount} live · ${appCount || apps?.length || 0} app${(appCount || apps?.length || 0) === 1 ? "" : "s"}`}
|
|
43
|
+
className="workspace-apps-linkage-section workspace-codex-sites-section"
|
|
44
|
+
>
|
|
45
|
+
<div className="workspace-app-row">
|
|
46
|
+
<span className="workspace-provider-mark"><Rocket size={15} /></span>
|
|
47
|
+
<div>
|
|
48
|
+
<strong>Codex Sites</strong>
|
|
49
|
+
<p>Manage Codex-hosted site URLs as a governed custom Data Model object attached to workspace apps and clients.</p>
|
|
50
|
+
<div className="workspace-integration-meta">
|
|
51
|
+
<span>{object ? "configured" : "not configured"}</span>
|
|
52
|
+
<span>{rows.length} site{rows.length === 1 ? "" : "s"}</span>
|
|
53
|
+
<span>{liveCount} live</span>
|
|
54
|
+
<span>{appCount || apps?.length || 0} app{(appCount || apps?.length || 0) === 1 ? "" : "s"}</span>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
<button type="button" className="workspace-settings-action" onClick={openDataModel}>
|
|
58
|
+
<ExternalLink size={14} />{object ? "Manage" : "Set up"}
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
61
|
+
{rows.length ? <div className="workspace-settings-codex-sites-list">
|
|
62
|
+
{rows.slice(0, 4).map((row, index) => isCodexSiteUrl(row?.url) ? (
|
|
63
|
+
<a key={row.id || row.Name || index} href={row.url} target="_blank" rel="noreferrer">
|
|
64
|
+
<span>{row.Name || `Site ${index + 1}`}</span>
|
|
65
|
+
<em>{row.client || "Workspace"} · {row.app || "apps/workspace"}</em>
|
|
66
|
+
<ExternalLink size={13} />
|
|
67
|
+
</a>
|
|
68
|
+
) : (
|
|
69
|
+
<button key={row.id || row.Name || index} type="button" onClick={openDataModel}>
|
|
70
|
+
<span>{row.Name || `Site ${index + 1}`}</span>
|
|
71
|
+
<em>{row.client || "Workspace"} · {row.status || "draft"}</em>
|
|
72
|
+
</button>
|
|
73
|
+
))}
|
|
74
|
+
</div> : null}
|
|
75
|
+
</SettingsAccordionSection>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
CODEX_SITES_OBJECT_ID,
|
|
80
|
+
CodexSitesDataModelCard
|
|
81
|
+
};
|