@ggui-ai/dev-stack 0.17.0 → 0.19.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/dist/hub-preview/client.js +98 -10
- package/package.json +7 -7
|
@@ -20526,6 +20526,7 @@ function useAction(actionName) {
|
|
|
20526
20526
|
if (onDispatchSuppressed) {
|
|
20527
20527
|
try {
|
|
20528
20528
|
onDispatchSuppressed({
|
|
20529
|
+
reason: "duplicate-dispatch",
|
|
20529
20530
|
actionName,
|
|
20530
20531
|
payloadSignature: decision.signature,
|
|
20531
20532
|
payload: data,
|
|
@@ -20798,11 +20799,26 @@ function buildWireConfig(opts) {
|
|
|
20798
20799
|
return internalSeq;
|
|
20799
20800
|
});
|
|
20800
20801
|
const validateEnvelope = opts.validateEnvelope ?? validateOutboundActionEnvelope;
|
|
20802
|
+
const spentOneShots = /* @__PURE__ */ new Set();
|
|
20801
20803
|
return {
|
|
20802
20804
|
app: opts.app,
|
|
20803
20805
|
render: opts.render,
|
|
20804
20806
|
auth: opts.auth,
|
|
20807
|
+
...opts.onDispatchSuppressed !== void 0 ? { onDispatchSuppressed: opts.onDispatchSuppressed } : {},
|
|
20805
20808
|
dispatch: (actionName, data) => {
|
|
20809
|
+
const actionSpec = opts.getActiveActionSpec();
|
|
20810
|
+
const isOneShot = actionSpec?.[actionName]?.oneShot === true;
|
|
20811
|
+
if (isOneShot && spentOneShots.has(actionName)) {
|
|
20812
|
+
console.warn(`[ggui] dispatch('${actionName}') suppressed: this action is declared oneShot and already fired for this render. A second gesture is NOT sent to the agent \u2014 the submitted control is spent for the render's lifetime. If the action is meant to repeat, remove \`oneShot\` from its contract entry.`);
|
|
20813
|
+
opts.onDispatchSuppressed?.({
|
|
20814
|
+
reason: "one-shot-spent",
|
|
20815
|
+
actionName,
|
|
20816
|
+
payloadSignature: payloadSignature(actionName, data),
|
|
20817
|
+
payload: data,
|
|
20818
|
+
suppressedAt: Date.now()
|
|
20819
|
+
});
|
|
20820
|
+
return;
|
|
20821
|
+
}
|
|
20806
20822
|
const envelope = buildActionEnvelope({
|
|
20807
20823
|
sessionId: opts.render.sessionId,
|
|
20808
20824
|
type: "data:submit",
|
|
@@ -20812,11 +20828,13 @@ function buildWireConfig(opts) {
|
|
|
20812
20828
|
},
|
|
20813
20829
|
clientSeq: nextClientSeq()
|
|
20814
20830
|
});
|
|
20815
|
-
const result = validateEnvelope(
|
|
20831
|
+
const result = validateEnvelope(actionSpec, envelope);
|
|
20816
20832
|
if (!result.valid) {
|
|
20817
20833
|
opts.onViolation(new ClientContractViolationError("outbound-action", result.violations));
|
|
20818
20834
|
return;
|
|
20819
20835
|
}
|
|
20836
|
+
if (isOneShot)
|
|
20837
|
+
spentOneShots.add(actionName);
|
|
20820
20838
|
opts.emitEnvelope(envelope);
|
|
20821
20839
|
},
|
|
20822
20840
|
subscribe: (channelName, handler) => {
|
|
@@ -21645,7 +21663,7 @@ function Button({ children, variant = "primary", size = "md", fullWidth, loading
|
|
|
21645
21663
|
alignItems: "center",
|
|
21646
21664
|
justifyContent: "center",
|
|
21647
21665
|
gap: "var(--ggui-spacing-2, 8px)",
|
|
21648
|
-
borderRadius: "var(--ggui-shape-radius-md, 8px)",
|
|
21666
|
+
borderRadius: "var(--ggui-shape-radius-control, var(--ggui-shape-radius-md, 8px))",
|
|
21649
21667
|
fontWeight: "var(--ggui-font-weight-medium, 500)",
|
|
21650
21668
|
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
21651
21669
|
opacity: isDisabled ? 0.5 : 1,
|
|
@@ -21687,7 +21705,7 @@ function Input({ label, placeholder, value, onChange, type = "text", error, help
|
|
|
21687
21705
|
}, children: [label, required && (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "2px" }, children: "*" })] }), (0, import_jsx_runtime11.jsx)("input", { id: inputId, type, placeholder, value, onChange: (e) => onChange?.(e.target.value), disabled, required, "aria-invalid": hasError || void 0, "aria-describedby": hasMessage ? messageId : void 0, style: {
|
|
21688
21706
|
...sizeStyles2[size],
|
|
21689
21707
|
width: "100%",
|
|
21690
|
-
borderRadius: "var(--ggui-shape-radius-md, 8px)",
|
|
21708
|
+
borderRadius: "var(--ggui-shape-radius-control, var(--ggui-shape-radius-md, 8px))",
|
|
21691
21709
|
border: `1px solid ${hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-outline, #d4d4d8)"}`,
|
|
21692
21710
|
backgroundColor: disabled ? "var(--ggui-color-sunken, #fafafa)" : "var(--ggui-color-sunken, #ffffff)",
|
|
21693
21711
|
color: "var(--ggui-color-onContainer, #18181b)",
|
|
@@ -21717,7 +21735,7 @@ function TextArea({ label, placeholder, value, onChange, rows = 4, error, helper
|
|
|
21717
21735
|
}, children: [label, required && (0, import_jsx_runtime12.jsx)("span", { "aria-hidden": "true", style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "2px" }, children: "*" })] }), (0, import_jsx_runtime12.jsx)("textarea", { id: textareaId, placeholder, value, onChange: (e) => onChange?.(e.target.value), rows, disabled, required, maxLength, "aria-invalid": hasError || void 0, "aria-describedby": hasMessage ? messageId : void 0, style: {
|
|
21718
21736
|
padding: "10px 12px",
|
|
21719
21737
|
width: "100%",
|
|
21720
|
-
borderRadius: "var(--ggui-shape-radius-md, 8px)",
|
|
21738
|
+
borderRadius: "var(--ggui-shape-radius-control, var(--ggui-shape-radius-md, 8px))",
|
|
21721
21739
|
border: `1px solid ${hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-outline, #d4d4d8)"}`,
|
|
21722
21740
|
backgroundColor: disabled ? "var(--ggui-color-sunken, #fafafa)" : "var(--ggui-color-sunken, #ffffff)",
|
|
21723
21741
|
color: "var(--ggui-color-onContainer, #18181b)",
|
|
@@ -21753,7 +21771,7 @@ function Select({ label, value, onChange, options, placeholder, error, helperTex
|
|
|
21753
21771
|
}, children: [label, required && (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": "true", style: { color: "var(--ggui-color-error-500, #ef4444)", marginLeft: "2px" }, children: "*" })] }), (0, import_jsx_runtime13.jsxs)("select", { id: selectId, value, onChange: (e) => onChange?.(e.target.value), disabled, required, "aria-invalid": hasError || void 0, "aria-describedby": hasMessage ? messageId : void 0, style: {
|
|
21754
21772
|
...sizeStyles3[size],
|
|
21755
21773
|
width: "100%",
|
|
21756
|
-
borderRadius: "var(--ggui-shape-radius-md, 8px)",
|
|
21774
|
+
borderRadius: "var(--ggui-shape-radius-control, var(--ggui-shape-radius-md, 8px))",
|
|
21757
21775
|
border: `1px solid ${hasError ? "var(--ggui-color-error-500, #ef4444)" : "var(--ggui-color-outline, #d4d4d8)"}`,
|
|
21758
21776
|
backgroundColor: disabled ? "var(--ggui-color-sunken, #fafafa)" : "var(--ggui-color-sunken, #ffffff)",
|
|
21759
21777
|
color: value ? "var(--ggui-color-onContainer, #18181b)" : "var(--ggui-color-onSunken, #52525b)",
|
|
@@ -29431,6 +29449,7 @@ var consumed_tokens_manifest_default = {
|
|
|
29431
29449
|
"--ggui-font-weight-normal",
|
|
29432
29450
|
"--ggui-font-weight-semibold",
|
|
29433
29451
|
"--ggui-letter-spacing-heading",
|
|
29452
|
+
"--ggui-shape-radius-control",
|
|
29434
29453
|
"--ggui-shape-radius-full",
|
|
29435
29454
|
"--ggui-shape-radius-lg",
|
|
29436
29455
|
"--ggui-shape-radius-md",
|
|
@@ -29579,6 +29598,8 @@ var NEUTRAL_T = [0.04, 0.08, 0.16, 0.28, 0.44, 0.58, 0.7, 0.8, 0.9, 0.96];
|
|
|
29579
29598
|
var FAMILIES = ["primary", "tertiary", "success", "warning", "error", "info"];
|
|
29580
29599
|
var NAMED_SPACING = { xs: "4px", sm: "8px", md: "16px", lg: "24px", xl: "32px", "2xl": "48px" };
|
|
29581
29600
|
var SIZE_EXP = { xs: -2, sm: -1, base: 0, lg: 1, xl: 2, "2xl": 3, "3xl": 4, "4xl": 5 };
|
|
29601
|
+
var ROLE_STOP = { display: "4xl", h1: "3xl", h2: "2xl", body: "base", label: "xs" };
|
|
29602
|
+
var LAYER1_SPACING_UNIT_PX = 4;
|
|
29582
29603
|
function tokenValue(t) {
|
|
29583
29604
|
if (t === void 0 || t === null || typeof t !== "object" || !("$value" in t))
|
|
29584
29605
|
return void 0;
|
|
@@ -29589,6 +29610,24 @@ function tokenValue(t) {
|
|
|
29589
29610
|
return void 0;
|
|
29590
29611
|
return /^#[0-9a-fA-F]{3,6}$/.test(v) ? `#${parseHex(v).map((n) => n.toString(16).padStart(2, "0")).join("")}` : v;
|
|
29591
29612
|
}
|
|
29613
|
+
function describeFound(t) {
|
|
29614
|
+
if (t === null)
|
|
29615
|
+
return "null";
|
|
29616
|
+
if (typeof t !== "object")
|
|
29617
|
+
return `${typeof t} ${JSON.stringify(t)}`;
|
|
29618
|
+
return "$value" in t ? "object with a non-string, non-number $value" : "object without $value";
|
|
29619
|
+
}
|
|
29620
|
+
var defaultDiagnostic = (d) => {
|
|
29621
|
+
console.warn(`[ggui-design] theme member unreadable at ${d.path} \u2014 found ${d.found}; expected a DTCG token ({ $value }). The member was ignored and the fallback used.`);
|
|
29622
|
+
};
|
|
29623
|
+
function readToken(t, path, report) {
|
|
29624
|
+
if (t === void 0)
|
|
29625
|
+
return void 0;
|
|
29626
|
+
const v = tokenValue(t);
|
|
29627
|
+
if (v === void 0)
|
|
29628
|
+
report({ kind: "member-unreadable", path, found: describeFound(t) });
|
|
29629
|
+
return v;
|
|
29630
|
+
}
|
|
29592
29631
|
function stated(group, key) {
|
|
29593
29632
|
return tokenValue(group?.[key]);
|
|
29594
29633
|
}
|
|
@@ -29649,7 +29688,15 @@ function parseSize(value) {
|
|
|
29649
29688
|
const m = /^([0-9.]+)\s*(rem|px|em)$/.exec(value.trim());
|
|
29650
29689
|
return m ? { n: Number(m[1]), unit: m[2] } : void 0;
|
|
29651
29690
|
}
|
|
29652
|
-
function deriveThemeVariables(doc, mode) {
|
|
29691
|
+
function deriveThemeVariables(doc, mode, options = {}) {
|
|
29692
|
+
const reported = /* @__PURE__ */ new Set();
|
|
29693
|
+
const sink = options.onDiagnostic ?? defaultDiagnostic;
|
|
29694
|
+
const report = (d) => {
|
|
29695
|
+
if (reported.has(d.path))
|
|
29696
|
+
return;
|
|
29697
|
+
reported.add(d.path);
|
|
29698
|
+
sink(d);
|
|
29699
|
+
};
|
|
29653
29700
|
const c = Object.fromEntries(Object.entries(doc.color));
|
|
29654
29701
|
const single = (key) => tokenValue(c[key]);
|
|
29655
29702
|
const group = (key) => c[key];
|
|
@@ -29729,19 +29776,60 @@ function deriveThemeVariables(doc, mode) {
|
|
|
29729
29776
|
for (const lh of Object.keys(lineHeight))
|
|
29730
29777
|
V[`--ggui-font-lineHeight-${lh}`] = String(lineHeight[lh]);
|
|
29731
29778
|
const ramp = doc.font.ramp;
|
|
29732
|
-
const base = ramp ? parseSize(
|
|
29733
|
-
const ratio = ramp ? Number(
|
|
29779
|
+
const base = ramp ? parseSize(readToken(ramp.base, "font.ramp.base", report) ?? "") : void 0;
|
|
29780
|
+
const ratio = ramp ? Number(readToken(ramp.ratio, "font.ramp.ratio", report)) : NaN;
|
|
29734
29781
|
for (const [stop, exp] of Object.entries(SIZE_EXP)) {
|
|
29735
29782
|
V[`--ggui-font-size-${stop}`] = base && Number.isFinite(ratio) && ratio > 0 ? `${Math.round(base.n * ratio ** exp * 1e3) / 1e3}${base.unit}` : fontSize[stop];
|
|
29736
29783
|
}
|
|
29784
|
+
const typeScale = doc.typeScale;
|
|
29785
|
+
if (typeScale !== void 0) {
|
|
29786
|
+
const bodySize = parseSize(readToken(typeScale.body?.size, "typeScale.body.size", report) ?? "");
|
|
29787
|
+
if (bodySize !== void 0) {
|
|
29788
|
+
const r = Number.isFinite(ratio) && ratio > 0 ? ratio : 1.25;
|
|
29789
|
+
for (const [stop, exp] of Object.entries(SIZE_EXP)) {
|
|
29790
|
+
V[`--ggui-font-size-${stop}`] = `${Math.round(bodySize.n * r ** exp * 1e3) / 1e3}${bodySize.unit}`;
|
|
29791
|
+
}
|
|
29792
|
+
}
|
|
29793
|
+
for (const [role, stop] of Object.entries(ROLE_STOP)) {
|
|
29794
|
+
const size = readToken(typeScale[role]?.size, `typeScale.${role}.size`, report);
|
|
29795
|
+
if (size !== void 0)
|
|
29796
|
+
V[`--ggui-font-size-${stop}`] = size;
|
|
29797
|
+
}
|
|
29798
|
+
const headingWeight = readToken(typeScale.h1?.weight, "typeScale.h1.weight", report);
|
|
29799
|
+
if (headingWeight !== void 0)
|
|
29800
|
+
V["--ggui-font-weight-heading"] = headingWeight;
|
|
29801
|
+
const bodyWeight = readToken(typeScale.body?.weight, "typeScale.body.weight", report);
|
|
29802
|
+
if (bodyWeight !== void 0)
|
|
29803
|
+
V["--ggui-font-weight-normal"] = bodyWeight;
|
|
29804
|
+
const headingTracking = readToken(typeScale.h1?.tracking, "typeScale.h1.tracking", report);
|
|
29805
|
+
if (headingTracking !== void 0)
|
|
29806
|
+
V["--ggui-letter-spacing-heading"] = headingTracking;
|
|
29807
|
+
const bodyTracking = readToken(typeScale.body?.tracking, "typeScale.body.tracking", report);
|
|
29808
|
+
if (bodyTracking !== void 0)
|
|
29809
|
+
V["--ggui-letter-spacing-body"] = bodyTracking;
|
|
29810
|
+
const bodyLeading = readToken(typeScale.body?.leading, "typeScale.body.leading", report);
|
|
29811
|
+
if (bodyLeading !== void 0)
|
|
29812
|
+
V["--ggui-font-lineHeight-normal"] = bodyLeading;
|
|
29813
|
+
}
|
|
29737
29814
|
const sp = doc.spacing;
|
|
29815
|
+
const rhythmBase = doc.rhythm ? parseSize(readToken(doc.rhythm.base, "rhythm.base", report) ?? "") : void 0;
|
|
29816
|
+
const onRhythm = (layer1) => {
|
|
29817
|
+
if (rhythmBase === void 0)
|
|
29818
|
+
return void 0;
|
|
29819
|
+
const step = parseSize(layer1);
|
|
29820
|
+
if (step === void 0)
|
|
29821
|
+
return void 0;
|
|
29822
|
+
const scaled = step.n / LAYER1_SPACING_UNIT_PX * rhythmBase.n;
|
|
29823
|
+
return `${Math.round(scaled * 1e3) / 1e3}${rhythmBase.unit}`;
|
|
29824
|
+
};
|
|
29738
29825
|
for (const [key, value] of Object.entries(spacing))
|
|
29739
|
-
V[`--ggui-spacing-${key}`] = stated(sp, key) ?? String(value);
|
|
29826
|
+
V[`--ggui-spacing-${key}`] = onRhythm(String(value)) ?? stated(sp, key) ?? String(value);
|
|
29740
29827
|
for (const [key, value] of Object.entries(NAMED_SPACING))
|
|
29741
|
-
V[`--ggui-spacing-${key}`] = stated(sp, key) ?? value;
|
|
29828
|
+
V[`--ggui-spacing-${key}`] = onRhythm(value) ?? stated(sp, key) ?? value;
|
|
29742
29829
|
const rad = doc.shape?.radius;
|
|
29743
29830
|
for (const [key, value] of Object.entries(radius))
|
|
29744
29831
|
V[`--ggui-shape-radius-${key}`] = stated(rad, key) ?? String(value);
|
|
29832
|
+
V["--ggui-shape-radius-control"] = stated(rad, "control") ?? V["--ggui-shape-radius-md"];
|
|
29745
29833
|
const sh = doc.shape?.shadow;
|
|
29746
29834
|
for (const [key, value] of Object.entries(shadow))
|
|
29747
29835
|
V[`--ggui-shape-shadow-${key}`] = stated(sh, key) ?? String(value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/dev-stack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Shared local dev engine for the ggui protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ggui",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"chokidar": "^4.0.3",
|
|
30
30
|
"esbuild": "^0.28.2",
|
|
31
|
-
"@ggui-ai/agent-runtime": "0.
|
|
32
|
-
"@ggui-ai/project-config": "0.
|
|
33
|
-
"@ggui-ai/ui-registry": "0.
|
|
31
|
+
"@ggui-ai/agent-runtime": "0.19.0",
|
|
32
|
+
"@ggui-ai/project-config": "0.19.0",
|
|
33
|
+
"@ggui-ai/ui-registry": "0.19.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^24.0.0",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"react-dom": "^19.0.0",
|
|
41
41
|
"typescript": "^5.0.0",
|
|
42
42
|
"vitest": "^3.2.6",
|
|
43
|
-
"@ggui-ai/design": "0.
|
|
44
|
-
"@ggui-ai/mcp-apps-react": "0.
|
|
45
|
-
"@ggui-ai/wire": "0.
|
|
43
|
+
"@ggui-ai/design": "0.19.0",
|
|
44
|
+
"@ggui-ai/mcp-apps-react": "0.19.0",
|
|
45
|
+
"@ggui-ai/wire": "0.19.0"
|
|
46
46
|
},
|
|
47
47
|
"repository": {
|
|
48
48
|
"type": "git",
|