@ggui-ai/dev-stack 0.18.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 +62 -16
- 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",
|
|
@@ -29591,6 +29610,24 @@ function tokenValue(t) {
|
|
|
29591
29610
|
return void 0;
|
|
29592
29611
|
return /^#[0-9a-fA-F]{3,6}$/.test(v) ? `#${parseHex(v).map((n) => n.toString(16).padStart(2, "0")).join("")}` : v;
|
|
29593
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
|
+
}
|
|
29594
29631
|
function stated(group, key) {
|
|
29595
29632
|
return tokenValue(group?.[key]);
|
|
29596
29633
|
}
|
|
@@ -29651,7 +29688,15 @@ function parseSize(value) {
|
|
|
29651
29688
|
const m = /^([0-9.]+)\s*(rem|px|em)$/.exec(value.trim());
|
|
29652
29689
|
return m ? { n: Number(m[1]), unit: m[2] } : void 0;
|
|
29653
29690
|
}
|
|
29654
|
-
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
|
+
};
|
|
29655
29700
|
const c = Object.fromEntries(Object.entries(doc.color));
|
|
29656
29701
|
const single = (key) => tokenValue(c[key]);
|
|
29657
29702
|
const group = (key) => c[key];
|
|
@@ -29731,14 +29776,14 @@ function deriveThemeVariables(doc, mode) {
|
|
|
29731
29776
|
for (const lh of Object.keys(lineHeight))
|
|
29732
29777
|
V[`--ggui-font-lineHeight-${lh}`] = String(lineHeight[lh]);
|
|
29733
29778
|
const ramp = doc.font.ramp;
|
|
29734
|
-
const base = ramp ? parseSize(
|
|
29735
|
-
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;
|
|
29736
29781
|
for (const [stop, exp] of Object.entries(SIZE_EXP)) {
|
|
29737
29782
|
V[`--ggui-font-size-${stop}`] = base && Number.isFinite(ratio) && ratio > 0 ? `${Math.round(base.n * ratio ** exp * 1e3) / 1e3}${base.unit}` : fontSize[stop];
|
|
29738
29783
|
}
|
|
29739
29784
|
const typeScale = doc.typeScale;
|
|
29740
29785
|
if (typeScale !== void 0) {
|
|
29741
|
-
const bodySize = parseSize(
|
|
29786
|
+
const bodySize = parseSize(readToken(typeScale.body?.size, "typeScale.body.size", report) ?? "");
|
|
29742
29787
|
if (bodySize !== void 0) {
|
|
29743
29788
|
const r = Number.isFinite(ratio) && ratio > 0 ? ratio : 1.25;
|
|
29744
29789
|
for (const [stop, exp] of Object.entries(SIZE_EXP)) {
|
|
@@ -29746,28 +29791,28 @@ function deriveThemeVariables(doc, mode) {
|
|
|
29746
29791
|
}
|
|
29747
29792
|
}
|
|
29748
29793
|
for (const [role, stop] of Object.entries(ROLE_STOP)) {
|
|
29749
|
-
const size =
|
|
29794
|
+
const size = readToken(typeScale[role]?.size, `typeScale.${role}.size`, report);
|
|
29750
29795
|
if (size !== void 0)
|
|
29751
29796
|
V[`--ggui-font-size-${stop}`] = size;
|
|
29752
29797
|
}
|
|
29753
|
-
const headingWeight =
|
|
29798
|
+
const headingWeight = readToken(typeScale.h1?.weight, "typeScale.h1.weight", report);
|
|
29754
29799
|
if (headingWeight !== void 0)
|
|
29755
29800
|
V["--ggui-font-weight-heading"] = headingWeight;
|
|
29756
|
-
const bodyWeight =
|
|
29801
|
+
const bodyWeight = readToken(typeScale.body?.weight, "typeScale.body.weight", report);
|
|
29757
29802
|
if (bodyWeight !== void 0)
|
|
29758
29803
|
V["--ggui-font-weight-normal"] = bodyWeight;
|
|
29759
|
-
const headingTracking =
|
|
29804
|
+
const headingTracking = readToken(typeScale.h1?.tracking, "typeScale.h1.tracking", report);
|
|
29760
29805
|
if (headingTracking !== void 0)
|
|
29761
29806
|
V["--ggui-letter-spacing-heading"] = headingTracking;
|
|
29762
|
-
const bodyTracking =
|
|
29807
|
+
const bodyTracking = readToken(typeScale.body?.tracking, "typeScale.body.tracking", report);
|
|
29763
29808
|
if (bodyTracking !== void 0)
|
|
29764
29809
|
V["--ggui-letter-spacing-body"] = bodyTracking;
|
|
29765
|
-
const bodyLeading =
|
|
29810
|
+
const bodyLeading = readToken(typeScale.body?.leading, "typeScale.body.leading", report);
|
|
29766
29811
|
if (bodyLeading !== void 0)
|
|
29767
29812
|
V["--ggui-font-lineHeight-normal"] = bodyLeading;
|
|
29768
29813
|
}
|
|
29769
29814
|
const sp = doc.spacing;
|
|
29770
|
-
const rhythmBase = doc.rhythm ? parseSize(
|
|
29815
|
+
const rhythmBase = doc.rhythm ? parseSize(readToken(doc.rhythm.base, "rhythm.base", report) ?? "") : void 0;
|
|
29771
29816
|
const onRhythm = (layer1) => {
|
|
29772
29817
|
if (rhythmBase === void 0)
|
|
29773
29818
|
return void 0;
|
|
@@ -29784,6 +29829,7 @@ function deriveThemeVariables(doc, mode) {
|
|
|
29784
29829
|
const rad = doc.shape?.radius;
|
|
29785
29830
|
for (const [key, value] of Object.entries(radius))
|
|
29786
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"];
|
|
29787
29833
|
const sh = doc.shape?.shadow;
|
|
29788
29834
|
for (const [key, value] of Object.entries(shadow))
|
|
29789
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",
|