@xenosystem/blocks 0.13.14 → 0.13.15
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/trust/index.d.ts +119 -17
- package/dist/trust/index.js +334 -198
- package/package.json +3 -3
package/dist/trust/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PanelModule, PanelManifest } from '@xenosystem/block-sdk';
|
|
1
|
+
import { PanelModule, PanelManifest, BlockDeclaration } from '@xenosystem/block-sdk';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -750,31 +750,133 @@ declare const CONSENT_PANEL_ID = "xeno.core.consent";
|
|
|
750
750
|
declare const consentManifest: PanelManifest;
|
|
751
751
|
|
|
752
752
|
/**
|
|
753
|
-
* The Consent panel
|
|
753
|
+
* The Consent panel AS A DECLARATION — the seventeenth declared block: one elicitation at a time,
|
|
754
|
+
* a PERMISSION (scopes + how long) or a QUESTION (options and/or a typed answer), never in bulk.
|
|
755
|
+
*
|
|
756
|
+
* Everything drawn is data: the header (risk and kind badges, the subject, the waiting count), the
|
|
757
|
+
* request (title, detail, its facts as `KeyValue`s), the permission's scope rows with a `Toggle`
|
|
758
|
+
* each and the duration control, or the question's option rows and the answer field with its
|
|
759
|
+
* length counter, Deny / Allow or Cancel / Submit, the status bar with the expiry. Every rule the
|
|
760
|
+
* code view carried survives: a question has no "deny" — refusing is a CANCELLATION, and the two
|
|
761
|
+
* are different outcomes for the host; no auto-focus on Allow, so a stray Enter grants nothing;
|
|
762
|
+
* the button's `disabled` is the SAME predicate `submit()` enforces. No runtime-bound unit.
|
|
763
|
+
*/
|
|
764
|
+
|
|
765
|
+
type Tone = 'neutral' | 'warning' | 'error';
|
|
766
|
+
interface ConsentViewFact {
|
|
767
|
+
key: string;
|
|
768
|
+
value: string;
|
|
769
|
+
}
|
|
770
|
+
interface ConsentViewScope {
|
|
771
|
+
id: string;
|
|
772
|
+
label: string;
|
|
773
|
+
detail?: string;
|
|
774
|
+
risk?: string;
|
|
775
|
+
riskTone: Tone;
|
|
776
|
+
granted: boolean;
|
|
777
|
+
grantable: boolean;
|
|
778
|
+
toggleLabel: string;
|
|
779
|
+
selected: boolean;
|
|
780
|
+
}
|
|
781
|
+
interface ConsentViewOption {
|
|
782
|
+
id: string;
|
|
783
|
+
label: string;
|
|
784
|
+
detail?: string;
|
|
785
|
+
risk?: string;
|
|
786
|
+
riskTone: Tone;
|
|
787
|
+
toggleLabel: string;
|
|
788
|
+
selected: boolean;
|
|
789
|
+
}
|
|
790
|
+
interface ConsentViewModel {
|
|
791
|
+
idle: boolean;
|
|
792
|
+
emptyHint: string;
|
|
793
|
+
active: boolean;
|
|
794
|
+
riskLabel: string;
|
|
795
|
+
riskTone: Tone;
|
|
796
|
+
kindLabel: string;
|
|
797
|
+
subject?: string;
|
|
798
|
+
waiting?: string;
|
|
799
|
+
title: string;
|
|
800
|
+
detail?: string;
|
|
801
|
+
facts: ConsentViewFact[];
|
|
802
|
+
permission: boolean;
|
|
803
|
+
scopes: ConsentViewScope[];
|
|
804
|
+
durations: {
|
|
805
|
+
value: string;
|
|
806
|
+
label: string;
|
|
807
|
+
}[];
|
|
808
|
+
duration: string;
|
|
809
|
+
unrememberable: boolean;
|
|
810
|
+
allowDisabled: boolean;
|
|
811
|
+
question: boolean;
|
|
812
|
+
hasOptions: boolean;
|
|
813
|
+
options: ConsentViewOption[];
|
|
814
|
+
wantsText: boolean;
|
|
815
|
+
textLabel?: string;
|
|
816
|
+
multiline: boolean;
|
|
817
|
+
placeholder: string;
|
|
818
|
+
draft: string;
|
|
819
|
+
hasCounter: boolean;
|
|
820
|
+
counter: string;
|
|
821
|
+
overLimit: boolean;
|
|
822
|
+
submitLabel: string;
|
|
823
|
+
submitDisabled: boolean;
|
|
824
|
+
pendingLabel: string;
|
|
825
|
+
expiryLabel?: string;
|
|
826
|
+
}
|
|
827
|
+
type ConsentUiIntent = {
|
|
828
|
+
kind: 'scope';
|
|
829
|
+
id: string;
|
|
830
|
+
on: boolean;
|
|
831
|
+
} | {
|
|
832
|
+
kind: 'duration';
|
|
833
|
+
duration: XenoConsentDuration;
|
|
834
|
+
} | {
|
|
835
|
+
kind: 'option';
|
|
836
|
+
id: string;
|
|
837
|
+
on: boolean;
|
|
838
|
+
} | {
|
|
839
|
+
kind: 'text';
|
|
840
|
+
value: string;
|
|
841
|
+
} | {
|
|
842
|
+
kind: 'allow';
|
|
843
|
+
} | {
|
|
844
|
+
kind: 'deny';
|
|
845
|
+
} | {
|
|
846
|
+
kind: 'submit';
|
|
847
|
+
} | {
|
|
848
|
+
kind: 'dismiss';
|
|
849
|
+
};
|
|
850
|
+
interface ConsentViewOptions {
|
|
851
|
+
showQueueCount?: boolean;
|
|
852
|
+
emptyHint?: string;
|
|
853
|
+
}
|
|
854
|
+
/** Derive the view from the live controller — the runtime calls this on every draw. */
|
|
855
|
+
declare function consentViewState(c: ConsentController, options?: ConsentViewOptions): ConsentViewModel;
|
|
856
|
+
declare function applyConsentUi(c: ConsentController, intent: ConsentUiIntent): void;
|
|
857
|
+
declare const consentViewManifest: PanelManifest;
|
|
858
|
+
declare const BEHAVIOURS: {
|
|
859
|
+
'trust/consentPanelView': (inputs: Record<string, unknown>) => ConsentViewModel;
|
|
860
|
+
};
|
|
861
|
+
declare const CONSENT_RUNTIME_UNITS: readonly [];
|
|
862
|
+
declare const CONSENT_DECLARATION: BlockDeclaration;
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* The Consent panel view — the CODE VIEW of `CONSENT_DECLARATION`, drawing the same
|
|
866
|
+
* `ConsentViewModel` byte-identical (the equivalence suite holds the two together). No runtime-bound
|
|
867
|
+
* unit; every intent goes through `applyConsentUi`.
|
|
754
868
|
*
|
|
755
869
|
* Composes `@xenosystem/components/chrome`; the host must ensure `@xenosystem/workbench/primitives.css` is
|
|
756
870
|
* present.
|
|
757
871
|
*
|
|
758
|
-
* Two deliberate absences: **no "Allow all"** (bulk approval is how consent fatigue becomes a
|
|
759
|
-
* security hole) and **no auto-focus on Allow** (a stray Enter must not grant anything).
|
|
760
|
-
*
|
|
761
|
-
* 🔴 **A third absence, added with the question kinds: nothing here submits on its own.** The
|
|
762
|
-
* question forms carry no auto-submit, no debounce-then-send, and no Enter-to-answer on the
|
|
763
|
-
* single-line field. The emitted answer is always the product of a click the user made, which is
|
|
764
|
-
* the view's half of the controller's *"no value without a user action"* invariant — the guard
|
|
765
|
-
* lives in `submit()`, but a view that fired it on a keystroke would satisfy the guard while
|
|
766
|
-
* defeating the point.
|
|
767
|
-
*
|
|
768
872
|
* @module
|
|
769
873
|
*/
|
|
770
874
|
|
|
771
875
|
/** Props for {@link ConsentPanelView}. */
|
|
772
|
-
interface ConsentPanelViewProps {
|
|
876
|
+
interface ConsentPanelViewProps extends ConsentViewOptions {
|
|
773
877
|
controller: ConsentController;
|
|
774
|
-
showQueueCount?: boolean;
|
|
775
|
-
emptyHint?: string;
|
|
776
878
|
}
|
|
777
879
|
/** The Consent panel view. */
|
|
778
|
-
declare function ConsentPanelView({ controller, showQueueCount, emptyHint
|
|
880
|
+
declare function ConsentPanelView({ controller, showQueueCount, emptyHint }: ConsentPanelViewProps): ReactNode;
|
|
779
881
|
|
|
780
|
-
export { CONSENT_PANEL_ID, ConsentController, type ConsentControllerOptions, type ConsentHostBridge, type ConsentPanelState, ConsentPanelView, type ConsentPanelViewProps, type ConsentRenderContext, type ConsentViewState, type CreateConsentPanelOptions, ELICITATION_RESULT_SCHEMA, ELICITATION_SCHEMA, type XenoChoiceAnswer, type XenoChoiceElicitation, type XenoConsentDecision, type XenoConsentDuration, type XenoConsentKind, type XenoConsentRequest, type XenoConsentRisk, type XenoConsentScope, type XenoElicitation, type XenoElicitationAnswer, type XenoElicitationAsk, type XenoElicitationBase, type XenoElicitationCancelled, type XenoElicitationOption, type XenoElicitationResult, type XenoPathAnswer, type XenoPathElicitation, type XenoQuestionElicitation, type XenoTextAnswer, type XenoTextElicitation, allowedDurations, autoCancel, autoDeny, consentManifest, consentPanel, createConsentPanel, effectiveRisk, elicitationAsk, elicitationOptions, findOption, isConsentRequest, isElicitation, isElicitationAnswer, isElicitationCancelled, isExpired, isPermissionElicitation, maxTextLength, selectableScopes };
|
|
882
|
+
export { BEHAVIOURS as CONSENT_BEHAVIOURS, CONSENT_DECLARATION, CONSENT_PANEL_ID, CONSENT_RUNTIME_UNITS, ConsentController, type ConsentControllerOptions, type ConsentHostBridge, type ConsentPanelState, ConsentPanelView, type ConsentPanelViewProps, type ConsentRenderContext, type ConsentUiIntent, type ConsentViewFact, type ConsentViewModel, type ConsentViewOption, type ConsentViewOptions, type ConsentViewScope, type ConsentViewState, type CreateConsentPanelOptions, ELICITATION_RESULT_SCHEMA, ELICITATION_SCHEMA, type XenoChoiceAnswer, type XenoChoiceElicitation, type XenoConsentDecision, type XenoConsentDuration, type XenoConsentKind, type XenoConsentRequest, type XenoConsentRisk, type XenoConsentScope, type XenoElicitation, type XenoElicitationAnswer, type XenoElicitationAsk, type XenoElicitationBase, type XenoElicitationCancelled, type XenoElicitationOption, type XenoElicitationResult, type XenoPathAnswer, type XenoPathElicitation, type XenoQuestionElicitation, type XenoTextAnswer, type XenoTextElicitation, allowedDurations, applyConsentUi, autoCancel, autoDeny, consentManifest, consentPanel, consentViewManifest, consentViewState, createConsentPanel, effectiveRisk, elicitationAsk, elicitationOptions, findOption, isConsentRequest, isElicitation, isElicitationAnswer, isElicitationCancelled, isExpired, isPermissionElicitation, maxTextLength, selectableScopes };
|
package/dist/trust/index.js
CHANGED
|
@@ -661,234 +661,364 @@ var consentManifest = {
|
|
|
661
661
|
import { useSyncExternalStore } from "react";
|
|
662
662
|
import {
|
|
663
663
|
Badge,
|
|
664
|
+
Column,
|
|
664
665
|
EmptyState,
|
|
666
|
+
Input,
|
|
667
|
+
KeyValue,
|
|
665
668
|
Row,
|
|
666
669
|
RowList,
|
|
667
670
|
ScrollArea,
|
|
668
671
|
SegmentedControl,
|
|
672
|
+
Stack,
|
|
669
673
|
StatusBar,
|
|
674
|
+
Text,
|
|
675
|
+
TextArea,
|
|
670
676
|
TextButton,
|
|
671
677
|
Toggle,
|
|
672
678
|
Toolbar,
|
|
673
679
|
ToolbarGroup
|
|
674
680
|
} from "@xenosystem/components/chrome";
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
medium: "warning",
|
|
679
|
-
high: "error"
|
|
680
|
-
};
|
|
681
|
+
|
|
682
|
+
// src/trust/consent/declaration.ts
|
|
683
|
+
var RISK_TONE = { low: "neutral", medium: "warning", high: "error" };
|
|
681
684
|
var DURATION_LABEL = { once: "Once", session: "Session", always: "Always" };
|
|
682
|
-
var
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
color: "inherit",
|
|
690
|
-
// 🔴 Text entry never takes the global focus ring: `outline-offset` draws it OUTSIDE the field,
|
|
691
|
-
// so on dark chrome it reads as a stray stroke over the container and the control looks broken.
|
|
692
|
-
outline: "none",
|
|
693
|
-
resize: "none"
|
|
694
|
-
};
|
|
695
|
-
var SUBMIT_LABEL = {
|
|
696
|
-
text: "Submit",
|
|
697
|
-
path: "Use this path",
|
|
698
|
-
choice: "Confirm"
|
|
699
|
-
};
|
|
700
|
-
function ConsentPanelView({
|
|
701
|
-
controller,
|
|
702
|
-
showQueueCount = true,
|
|
703
|
-
emptyHint
|
|
704
|
-
}) {
|
|
705
|
-
const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
|
|
706
|
-
const request = state.current;
|
|
685
|
+
var SUBMIT_LABEL = { text: "Submit", path: "Use this path", choice: "Confirm" };
|
|
686
|
+
function consentViewState(c, options = {}) {
|
|
687
|
+
const s = c.getState();
|
|
688
|
+
const request = s.current;
|
|
689
|
+
const showQueueCount = options.showQueueCount ?? true;
|
|
690
|
+
const emptyHint = options.emptyHint ?? "Requests needing your approval appear here.";
|
|
691
|
+
const base = { idle: !request, emptyHint, active: !!request };
|
|
707
692
|
if (!request) {
|
|
708
|
-
return
|
|
709
|
-
EmptyState,
|
|
710
|
-
{
|
|
711
|
-
title: "Nothing pending",
|
|
712
|
-
hint: emptyHint ?? "Requests needing your approval appear here."
|
|
713
|
-
}
|
|
714
|
-
);
|
|
693
|
+
return { ...base, riskLabel: "", riskTone: "neutral", kindLabel: "", title: "", facts: [], permission: false, scopes: [], durations: [], duration: "once", unrememberable: false, allowDisabled: true, question: false, hasOptions: false, options: [], wantsText: false, multiline: false, placeholder: "", draft: "", hasCounter: false, counter: "", overLimit: false, submitLabel: "Submit", submitDisabled: true, pendingLabel: `${s.pending} pending` };
|
|
715
694
|
}
|
|
716
695
|
const risk = effectiveRisk(request);
|
|
717
696
|
const ask = elicitationAsk(request);
|
|
718
697
|
const permission = isPermissionElicitation(request) ? request : null;
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
698
|
+
const opts = permission ? [] : elicitationOptions(request);
|
|
699
|
+
const chosen = opts.find((o) => o.id === s.selectedOptionId);
|
|
700
|
+
const max = permission ? null : maxTextLength(request);
|
|
701
|
+
const extra = request;
|
|
702
|
+
const wantsText = !permission && (ask !== "choice" || chosen?.requiresText === true);
|
|
703
|
+
return {
|
|
704
|
+
...base,
|
|
705
|
+
riskLabel: `${risk} risk`,
|
|
706
|
+
riskTone: RISK_TONE[risk],
|
|
707
|
+
kindLabel: permission ? permission.kind : ask,
|
|
708
|
+
subject: request.subject,
|
|
709
|
+
waiting: showQueueCount && s.queued.length > 0 ? `+${s.queued.length} waiting` : void 0,
|
|
710
|
+
title: request.title,
|
|
711
|
+
detail: request.detail,
|
|
712
|
+
facts: request.fields ? Object.entries(request.fields).map(([key, value]) => ({ key, value: String(value) })) : [],
|
|
713
|
+
permission: !!permission,
|
|
714
|
+
scopes: permission ? permission.scopes.map((scope) => ({
|
|
715
|
+
id: scope.id,
|
|
716
|
+
label: scope.label,
|
|
717
|
+
detail: scope.detail,
|
|
718
|
+
risk: scope.risk && scope.risk !== risk ? scope.risk : void 0,
|
|
719
|
+
riskTone: scope.risk ? RISK_TONE[scope.risk] : "neutral",
|
|
720
|
+
granted: scope.alreadyGranted === true,
|
|
721
|
+
grantable: scope.alreadyGranted !== true,
|
|
722
|
+
toggleLabel: `Grant ${scope.label}`,
|
|
723
|
+
selected: s.selectedScopeIds.includes(scope.id)
|
|
724
|
+
})) : [],
|
|
725
|
+
durations: permission ? allowedDurations(permission).map((d) => ({ value: d, label: DURATION_LABEL[d] })) : [],
|
|
726
|
+
duration: s.duration,
|
|
727
|
+
unrememberable: permission?.remember === "forbidden",
|
|
728
|
+
allowDisabled: !!permission && permission.scopes.some((sc) => !sc.alreadyGranted) && s.selectedScopeIds.length === 0,
|
|
729
|
+
question: !permission,
|
|
730
|
+
hasOptions: opts.length > 0,
|
|
731
|
+
options: opts.map((option) => ({
|
|
732
|
+
id: option.id,
|
|
733
|
+
label: option.label,
|
|
734
|
+
detail: option.detail,
|
|
735
|
+
risk: option.risk && option.risk !== risk ? option.risk : void 0,
|
|
736
|
+
riskTone: option.risk ? RISK_TONE[option.risk] : "neutral",
|
|
737
|
+
toggleLabel: `Choose ${option.label}`,
|
|
738
|
+
selected: s.selectedOptionId === option.id
|
|
739
|
+
})),
|
|
740
|
+
wantsText,
|
|
741
|
+
textLabel: extra.textLabel,
|
|
742
|
+
multiline: ask === "text" && extra.multiline === true,
|
|
743
|
+
placeholder: extra.placeholder ?? (ask === "path" ? "Type or paste a path\u2026" : "Type your answer\u2026"),
|
|
744
|
+
draft: s.draftText,
|
|
745
|
+
hasCounter: max !== null,
|
|
746
|
+
counter: max !== null ? `${s.draftText.length} / ${max}` : "",
|
|
747
|
+
overLimit: max !== null && s.draftText.length > max,
|
|
748
|
+
submitLabel: SUBMIT_LABEL[ask] ?? "Submit",
|
|
749
|
+
submitDisabled: !s.canSubmit,
|
|
750
|
+
pendingLabel: `${s.pending} pending`,
|
|
751
|
+
expiryLabel: s.expiresInMs !== null ? `expires in ${Math.ceil(s.expiresInMs / 1e3)}s \u2014 ${permission ? "denies" : "cancels"}` : void 0
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
function applyConsentUi(c, intent) {
|
|
755
|
+
switch (intent.kind) {
|
|
756
|
+
case "scope":
|
|
757
|
+
c.toggleScope(intent.id, intent.on);
|
|
758
|
+
break;
|
|
759
|
+
case "duration":
|
|
760
|
+
c.setDuration(intent.duration);
|
|
761
|
+
break;
|
|
762
|
+
case "option":
|
|
763
|
+
c.selectOption(intent.on ? intent.id : null);
|
|
764
|
+
break;
|
|
765
|
+
case "text":
|
|
766
|
+
c.setDraftText(intent.value);
|
|
767
|
+
break;
|
|
768
|
+
case "allow":
|
|
769
|
+
c.allow();
|
|
770
|
+
break;
|
|
771
|
+
case "deny":
|
|
772
|
+
c.deny();
|
|
773
|
+
break;
|
|
774
|
+
case "submit":
|
|
775
|
+
c.submit();
|
|
776
|
+
break;
|
|
777
|
+
case "dismiss":
|
|
778
|
+
c.dismiss();
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
var consentViewManifest = {
|
|
783
|
+
id: consentManifest.id,
|
|
784
|
+
version: "1.0.0",
|
|
785
|
+
title: "Consent",
|
|
786
|
+
category: "trust",
|
|
787
|
+
layout: { slot: "side" },
|
|
788
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The ConsentViewModel the runtime derives from the controller on every draw." }],
|
|
789
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
790
|
+
commands: []
|
|
791
|
+
};
|
|
792
|
+
var EMPTY = { idle: true, emptyHint: "Requests needing your approval appear here.", active: false, riskLabel: "", riskTone: "neutral", kindLabel: "", title: "", facts: [], permission: false, scopes: [], durations: [], duration: "once", unrememberable: false, allowDisabled: true, question: false, hasOptions: false, options: [], wantsText: false, multiline: false, placeholder: "", draft: "", hasCounter: false, counter: "", overLimit: false, submitLabel: "Submit", submitDisabled: true, pendingLabel: "0 pending" };
|
|
793
|
+
var BEHAVIOURS = {
|
|
794
|
+
"trust/consentPanelView": (inputs) => inputs.view ?? EMPTY
|
|
795
|
+
};
|
|
796
|
+
var CONSENT_RUNTIME_UNITS = [];
|
|
797
|
+
var text = (b) => ({ component: "text", props: { text: b } });
|
|
798
|
+
var ui = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
799
|
+
var twoLine = {
|
|
800
|
+
component: "chrome/Stack",
|
|
801
|
+
props: { gap: { value: 1 }, pad: { value: "none" } },
|
|
802
|
+
children: [{ component: "chrome/Text", children: [text({ item: "label" })] }, { component: "chrome/Text", when: { item: "detail" }, props: { role: { value: "meta" } }, children: [text({ item: "detail" })] }]
|
|
803
|
+
};
|
|
804
|
+
var riskMeta = { node: { component: "chrome/Badge", when: { item: "risk" }, props: { tone: { item: "riskTone" } }, children: [text({ item: "risk" })] } };
|
|
805
|
+
var CONSENT_DECLARATION = {
|
|
806
|
+
format: "xeno.block@1",
|
|
807
|
+
manifest: consentViewManifest,
|
|
808
|
+
behaviour: "trust/consentPanelView",
|
|
809
|
+
composition: {
|
|
810
|
+
component: "fragment",
|
|
811
|
+
children: [
|
|
812
|
+
{ component: "chrome/EmptyState", when: { input: "view.idle" }, props: { title: { value: "Nothing pending" }, hint: { input: "view.emptyHint" } } },
|
|
722
813
|
{
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
/* @__PURE__ */ jsx("code", { style: { userSelect: "all", wordBreak: "break-all" }, children: value })
|
|
741
|
-
] }, key)) : null
|
|
742
|
-
] }),
|
|
743
|
-
permission ? /* @__PURE__ */ jsx(RowList, { children: permission.scopes.map((scope) => /* @__PURE__ */ jsx(
|
|
744
|
-
Row,
|
|
745
|
-
{
|
|
746
|
-
noIcon: true,
|
|
747
|
-
label: /* @__PURE__ */ jsxs("span", { style: { display: "flex", flexDirection: "column", gap: 1, minWidth: 0 }, children: [
|
|
748
|
-
/* @__PURE__ */ jsx("span", { children: scope.label }),
|
|
749
|
-
scope.detail ? /* @__PURE__ */ jsx("span", { style: { fontSize: 10, opacity: 0.6 }, children: scope.detail }) : null
|
|
750
|
-
] }),
|
|
751
|
-
meta: scope.risk && scope.risk !== risk ? /* @__PURE__ */ jsx(Badge, { tone: RISK_TONE[scope.risk], children: scope.risk }) : null,
|
|
752
|
-
trailing: scope.alreadyGranted ? (
|
|
753
|
-
// Shown for context, not as a choice — hiding it would make the new ask look
|
|
754
|
-
// bigger than it is.
|
|
755
|
-
/* @__PURE__ */ jsx(Badge, { title: "Already granted", children: "granted" })
|
|
756
|
-
) : /* @__PURE__ */ jsx(
|
|
757
|
-
Toggle,
|
|
758
|
-
{
|
|
759
|
-
size: "sm",
|
|
760
|
-
label: `Grant ${scope.label}`,
|
|
761
|
-
checked: state.selectedScopeIds.includes(scope.id),
|
|
762
|
-
onChange: (next) => controller.toggleScope(scope.id, next)
|
|
814
|
+
component: "chrome/Column",
|
|
815
|
+
when: { input: "view.active" },
|
|
816
|
+
children: [
|
|
817
|
+
{
|
|
818
|
+
component: "chrome/Toolbar",
|
|
819
|
+
props: {
|
|
820
|
+
left: {
|
|
821
|
+
node: {
|
|
822
|
+
component: "fragment",
|
|
823
|
+
children: [
|
|
824
|
+
{ component: "chrome/Badge", props: { tone: { input: "view.riskTone" } }, children: [text({ input: "view.riskLabel" })] },
|
|
825
|
+
{ component: "chrome/Badge", children: [text({ input: "view.kindLabel" })] },
|
|
826
|
+
{ component: "chrome/Text", when: { input: "view.subject" }, children: [text({ input: "view.subject" })] }
|
|
827
|
+
]
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
right: { node: { component: "chrome/ToolbarGroup", when: { input: "view.waiting" }, props: { end: { value: true } }, children: [{ component: "chrome/Badge", props: { title: { value: "Answered one at a time \u2014 never in bulk." } }, children: [text({ input: "view.waiting" })] }] } }
|
|
763
831
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
component: "chrome/ScrollArea",
|
|
835
|
+
children: [
|
|
836
|
+
{
|
|
837
|
+
component: "chrome/Stack",
|
|
838
|
+
props: { gap: { value: 6 }, pad: { value: "gutter" } },
|
|
839
|
+
children: [
|
|
840
|
+
{ component: "chrome/Text", props: { role: { value: "title" } }, children: [text({ input: "view.title" })] },
|
|
841
|
+
{ component: "chrome/Text", when: { input: "view.detail" }, children: [text({ input: "view.detail" })] },
|
|
842
|
+
{ component: "chrome/KeyValue", each: { input: "view.facts", key: "key" }, props: { name: { item: "key" }, value: { item: "value" } } }
|
|
843
|
+
]
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
component: "chrome/RowList",
|
|
847
|
+
when: { input: "view.permission" },
|
|
848
|
+
children: [
|
|
849
|
+
{
|
|
850
|
+
component: "chrome/Row",
|
|
851
|
+
each: { input: "view.scopes", key: "id" },
|
|
852
|
+
props: {
|
|
853
|
+
noIcon: { value: true },
|
|
854
|
+
label: { node: twoLine },
|
|
855
|
+
meta: riskMeta,
|
|
856
|
+
trailing: {
|
|
857
|
+
node: {
|
|
858
|
+
component: "fragment",
|
|
859
|
+
children: [
|
|
860
|
+
{ component: "chrome/Badge", when: { item: "granted" }, props: { title: { value: "Already granted" } }, children: [text({ value: "granted" })] },
|
|
861
|
+
{ component: "chrome/Toggle", when: { item: "grantable" }, props: { size: { value: "sm" }, label: { item: "toggleLabel" }, checked: { item: "selected" } }, on: { onChange: ui("scope", { id: { item: "id" }, on: { arg: "" } }) } }
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
]
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
component: "chrome/Stack",
|
|
871
|
+
when: { input: "view.question" },
|
|
872
|
+
props: { gap: { value: 6 }, pad: { value: "inset" } },
|
|
873
|
+
children: [
|
|
874
|
+
{
|
|
875
|
+
component: "chrome/RowList",
|
|
876
|
+
when: { input: "view.hasOptions" },
|
|
877
|
+
children: [
|
|
878
|
+
{
|
|
879
|
+
component: "chrome/Row",
|
|
880
|
+
each: { input: "view.options", key: "id" },
|
|
881
|
+
props: { noIcon: { value: true }, label: { node: twoLine }, meta: riskMeta, trailing: { node: { component: "chrome/Toggle", props: { size: { value: "sm" }, label: { item: "toggleLabel" }, checked: { item: "selected" } }, on: { onChange: ui("option", { id: { item: "id" }, on: { arg: "" } }) } } } }
|
|
882
|
+
}
|
|
883
|
+
]
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
component: "chrome/Stack",
|
|
887
|
+
when: { input: "view.wantsText" },
|
|
888
|
+
props: { gap: { value: 3 }, pad: { value: "none" } },
|
|
889
|
+
children: [
|
|
890
|
+
{ component: "chrome/Text", when: { input: "view.textLabel" }, props: { role: { value: "meta" } }, children: [text({ input: "view.textLabel" })] },
|
|
891
|
+
{ component: "chrome/TextArea", when: { input: "view.multiline" }, props: { value: { input: "view.draft" }, placeholder: { input: "view.placeholder" }, rows: { value: 3 }, label: { value: "Answer" } }, on: { onChange: ui("text", { value: { arg: "" } }) } },
|
|
892
|
+
{ component: "chrome/Input", when: { not: { input: "view.multiline" } }, props: { value: { input: "view.draft" }, placeholder: { input: "view.placeholder" }, autoComplete: { value: "off" }, label: { value: "Answer" } }, on: { onChange: ui("text", { value: { arg: "" } }) } },
|
|
893
|
+
{ component: "chrome/Text", when: { input: "view.hasCounter" }, props: { role: { value: "caption" } }, children: [text({ input: "view.counter" })] },
|
|
894
|
+
{ component: "chrome/Badge", when: { input: "view.overLimit" }, props: { tone: { value: "error" } }, children: [text({ value: "too long" })] }
|
|
895
|
+
]
|
|
896
|
+
}
|
|
897
|
+
]
|
|
898
|
+
}
|
|
899
|
+
]
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
component: "chrome/Toolbar",
|
|
903
|
+
when: { input: "view.permission" },
|
|
904
|
+
props: {
|
|
905
|
+
divided: { value: false },
|
|
906
|
+
// Duration is IN the decision, not buried in a settings page.
|
|
907
|
+
left: { node: { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "How long" }, options: { input: "view.durations" }, value: { input: "view.duration" } }, on: { onChange: ui("duration", { duration: { arg: "" } }) } } },
|
|
908
|
+
right: { node: { component: "chrome/Text", when: { input: "view.unrememberable" }, props: { role: { value: "caption" } }, children: [text({ value: "This grant cannot be remembered." })] } }
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
component: "chrome/Toolbar",
|
|
913
|
+
props: {
|
|
914
|
+
divided: { value: false },
|
|
915
|
+
right: {
|
|
916
|
+
node: {
|
|
917
|
+
component: "chrome/ToolbarGroup",
|
|
918
|
+
props: { end: { value: true } },
|
|
919
|
+
children: [
|
|
920
|
+
{ component: "chrome/TextButton", when: { input: "view.permission" }, on: { onClick: ui("deny") }, children: [text({ value: "Deny" })] },
|
|
921
|
+
// No auto-focus: a stray Enter must not grant anything.
|
|
922
|
+
{ component: "chrome/TextButton", when: { input: "view.permission" }, props: { strong: { value: true }, disabled: { input: "view.allowDisabled" } }, on: { onClick: ui("allow") }, children: [text({ value: "Allow" })] },
|
|
923
|
+
// A question has no "deny" — refusing to answer is a CANCELLATION.
|
|
924
|
+
{ component: "chrome/TextButton", when: { input: "view.question" }, on: { onClick: ui("dismiss") }, children: [text({ value: "Cancel" })] },
|
|
925
|
+
{ component: "chrome/TextButton", when: { input: "view.question" }, props: { strong: { value: true }, disabled: { input: "view.submitDisabled" } }, on: { onClick: ui("submit") }, children: [text({ input: "view.submitLabel" })] }
|
|
926
|
+
]
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
{ component: "chrome/StatusBar", props: { left: { input: "view.pendingLabel" }, right: { input: "view.expiryLabel" } } }
|
|
932
|
+
]
|
|
933
|
+
}
|
|
934
|
+
]
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
// src/trust/consent/react/ConsentPanelView.tsx
|
|
939
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
940
|
+
var TwoLine = ({ label, detail }) => /* @__PURE__ */ jsxs(Stack, { gap: 1, pad: "none", children: [
|
|
941
|
+
/* @__PURE__ */ jsx(Text, { children: label }),
|
|
942
|
+
detail ? /* @__PURE__ */ jsx(Text, { role: "meta", children: detail }) : null
|
|
943
|
+
] });
|
|
944
|
+
function ConsentPanelView({ controller, showQueueCount, emptyHint }) {
|
|
945
|
+
useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
|
|
946
|
+
const view = consentViewState(controller, { showQueueCount, emptyHint });
|
|
947
|
+
const ui2 = (intent) => applyConsentUi(controller, intent);
|
|
948
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
949
|
+
view.idle ? /* @__PURE__ */ jsx(EmptyState, { title: "Nothing pending", hint: view.emptyHint }) : null,
|
|
950
|
+
view.active ? /* @__PURE__ */ jsxs(Column, { children: [
|
|
770
951
|
/* @__PURE__ */ jsx(
|
|
771
|
-
|
|
952
|
+
Toolbar,
|
|
772
953
|
{
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}))
|
|
779
|
-
value: state.duration,
|
|
780
|
-
onChange: (d) => controller.setDuration(d)
|
|
954
|
+
left: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
955
|
+
/* @__PURE__ */ jsx(Badge, { tone: view.riskTone, children: view.riskLabel }),
|
|
956
|
+
/* @__PURE__ */ jsx(Badge, { children: view.kindLabel }),
|
|
957
|
+
view.subject ? /* @__PURE__ */ jsx(Text, { children: view.subject }) : null
|
|
958
|
+
] }),
|
|
959
|
+
right: view.waiting ? /* @__PURE__ */ jsx(ToolbarGroup, { end: true, children: /* @__PURE__ */ jsx(Badge, { title: "Answered one at a time \u2014 never in bulk.", children: view.waiting }) }) : null
|
|
781
960
|
}
|
|
782
961
|
),
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
divided: false,
|
|
789
|
-
right: /* @__PURE__ */ jsx(ToolbarGroup, { end: true, children: permission ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
790
|
-
/* @__PURE__ */ jsx(TextButton, { onClick: () => controller.deny(), children: "Deny" }),
|
|
791
|
-
/* @__PURE__ */ jsx(
|
|
792
|
-
TextButton,
|
|
793
|
-
{
|
|
794
|
-
strong: true,
|
|
795
|
-
disabled: permission.scopes.some((s) => !s.alreadyGranted) && state.selectedScopeIds.length === 0,
|
|
796
|
-
onClick: () => controller.allow(),
|
|
797
|
-
children: "Allow"
|
|
798
|
-
}
|
|
799
|
-
)
|
|
800
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
801
|
-
/* @__PURE__ */ jsx(TextButton, { onClick: () => controller.dismiss(), children: "Cancel" }),
|
|
802
|
-
/* @__PURE__ */ jsx(
|
|
803
|
-
TextButton,
|
|
804
|
-
{
|
|
805
|
-
strong: true,
|
|
806
|
-
disabled: !state.canSubmit,
|
|
807
|
-
onClick: () => controller.submit(),
|
|
808
|
-
children: SUBMIT_LABEL[ask] ?? "Submit"
|
|
809
|
-
}
|
|
810
|
-
)
|
|
811
|
-
] }) })
|
|
812
|
-
}
|
|
813
|
-
),
|
|
814
|
-
/* @__PURE__ */ jsx(
|
|
815
|
-
StatusBar,
|
|
816
|
-
{
|
|
817
|
-
left: `${state.pending} pending`,
|
|
818
|
-
right: state.expiresInMs !== null ? `expires in ${Math.ceil(state.expiresInMs / 1e3)}s \u2014 ${permission ? "denies" : "cancels"}` : void 0
|
|
819
|
-
}
|
|
820
|
-
)
|
|
821
|
-
] });
|
|
822
|
-
}
|
|
823
|
-
function QuestionForm({ controller, request, state, risk }) {
|
|
824
|
-
const ask = elicitationAsk(request);
|
|
825
|
-
const options = elicitationOptions(request);
|
|
826
|
-
const max = maxTextLength(request);
|
|
827
|
-
const chosen = options.find((o) => o.id === state.selectedOptionId);
|
|
828
|
-
const multiline = ask === "text" && request.multiline === true;
|
|
829
|
-
const placeholder = request.placeholder ?? (ask === "path" ? "Type or paste a path\u2026" : "Type your answer\u2026");
|
|
830
|
-
const wantsText = ask !== "choice" || chosen?.requiresText === true;
|
|
831
|
-
const textLabel = request.textLabel;
|
|
832
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: "0 8px 8px", display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
833
|
-
options.length > 0 ? /* @__PURE__ */ jsx(RowList, { children: options.map((option) => /* @__PURE__ */ jsx(
|
|
834
|
-
Row,
|
|
835
|
-
{
|
|
836
|
-
noIcon: true,
|
|
837
|
-
label: /* @__PURE__ */ jsxs("span", { style: { display: "flex", flexDirection: "column", gap: 1, minWidth: 0 }, children: [
|
|
838
|
-
/* @__PURE__ */ jsx("span", { children: option.label }),
|
|
839
|
-
option.detail ? /* @__PURE__ */ jsx("span", { style: { fontSize: 10, opacity: 0.6 }, children: option.detail }) : null
|
|
962
|
+
/* @__PURE__ */ jsxs(ScrollArea, { children: [
|
|
963
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 6, pad: "gutter", children: [
|
|
964
|
+
/* @__PURE__ */ jsx(Text, { role: "title", children: view.title }),
|
|
965
|
+
view.detail ? /* @__PURE__ */ jsx(Text, { children: view.detail }) : null,
|
|
966
|
+
view.facts.map((f) => /* @__PURE__ */ jsx(KeyValue, { name: f.key, value: f.value }, f.key))
|
|
840
967
|
] }),
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
Toggle,
|
|
968
|
+
view.permission ? /* @__PURE__ */ jsx(RowList, { children: view.scopes.map((scope) => /* @__PURE__ */ jsx(
|
|
969
|
+
Row,
|
|
844
970
|
{
|
|
845
|
-
|
|
846
|
-
label:
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
971
|
+
noIcon: true,
|
|
972
|
+
label: /* @__PURE__ */ jsx(TwoLine, { label: scope.label, detail: scope.detail }),
|
|
973
|
+
meta: scope.risk ? /* @__PURE__ */ jsx(Badge, { tone: scope.riskTone, children: scope.risk }) : null,
|
|
974
|
+
trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
975
|
+
scope.granted ? /* @__PURE__ */ jsx(Badge, { title: "Already granted", children: "granted" }) : null,
|
|
976
|
+
scope.grantable ? /* @__PURE__ */ jsx(Toggle, { size: "sm", label: scope.toggleLabel, checked: scope.selected, onChange: (on) => ui2({ kind: "scope", id: scope.id, on }) }) : null
|
|
977
|
+
] })
|
|
978
|
+
},
|
|
979
|
+
scope.id
|
|
980
|
+
)) }) : null,
|
|
981
|
+
view.question ? /* @__PURE__ */ jsxs(Stack, { gap: 6, pad: "inset", children: [
|
|
982
|
+
view.hasOptions ? /* @__PURE__ */ jsx(RowList, { children: view.options.map((option) => /* @__PURE__ */ jsx(
|
|
983
|
+
Row,
|
|
984
|
+
{
|
|
985
|
+
noIcon: true,
|
|
986
|
+
label: /* @__PURE__ */ jsx(TwoLine, { label: option.label, detail: option.detail }),
|
|
987
|
+
meta: option.risk ? /* @__PURE__ */ jsx(Badge, { tone: option.riskTone, children: option.risk }) : null,
|
|
988
|
+
trailing: /* @__PURE__ */ jsx(Toggle, { size: "sm", label: option.toggleLabel, checked: option.selected, onChange: (on) => ui2({ kind: "option", id: option.id, on }) })
|
|
989
|
+
},
|
|
990
|
+
option.id
|
|
991
|
+
)) }) : null,
|
|
992
|
+
view.wantsText ? /* @__PURE__ */ jsxs(Stack, { gap: 3, pad: "none", children: [
|
|
993
|
+
view.textLabel ? /* @__PURE__ */ jsx(Text, { role: "meta", children: view.textLabel }) : null,
|
|
994
|
+
view.multiline ? /* @__PURE__ */ jsx(TextArea, { value: view.draft, placeholder: view.placeholder, rows: 3, label: "Answer", onChange: (value) => ui2({ kind: "text", value }) }) : null,
|
|
995
|
+
!view.multiline ? /* @__PURE__ */ jsx(Input, { value: view.draft, placeholder: view.placeholder, autoComplete: "off", label: "Answer", onChange: (value) => ui2({ kind: "text", value }) }) : null,
|
|
996
|
+
view.hasCounter ? /* @__PURE__ */ jsx(Text, { role: "caption", children: view.counter }) : null,
|
|
997
|
+
view.overLimit ? /* @__PURE__ */ jsx(Badge, { tone: "error", children: "too long" }) : null
|
|
998
|
+
] }) : null
|
|
999
|
+
] }) : null
|
|
1000
|
+
] }),
|
|
1001
|
+
view.permission ? /* @__PURE__ */ jsx(
|
|
1002
|
+
Toolbar,
|
|
858
1003
|
{
|
|
859
|
-
|
|
860
|
-
onChange: (
|
|
861
|
-
|
|
862
|
-
rows: 3,
|
|
863
|
-
spellCheck: false,
|
|
864
|
-
style: FIELD_STYLE
|
|
1004
|
+
divided: false,
|
|
1005
|
+
left: /* @__PURE__ */ jsx(SegmentedControl, { size: "sm", label: "How long", options: view.durations, value: view.duration, onChange: (duration) => ui2({ kind: "duration", duration }) }),
|
|
1006
|
+
right: view.unrememberable ? /* @__PURE__ */ jsx(Text, { role: "caption", children: "This grant cannot be remembered." }) : null
|
|
865
1007
|
}
|
|
866
|
-
) :
|
|
867
|
-
|
|
1008
|
+
) : null,
|
|
1009
|
+
/* @__PURE__ */ jsx(
|
|
1010
|
+
Toolbar,
|
|
868
1011
|
{
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1012
|
+
divided: false,
|
|
1013
|
+
right: /* @__PURE__ */ jsxs(ToolbarGroup, { end: true, children: [
|
|
1014
|
+
view.permission ? /* @__PURE__ */ jsx(TextButton, { onClick: () => ui2({ kind: "deny" }), children: "Deny" }) : null,
|
|
1015
|
+
view.permission ? /* @__PURE__ */ jsx(TextButton, { strong: true, disabled: view.allowDisabled, onClick: () => ui2({ kind: "allow" }), children: "Allow" }) : null,
|
|
1016
|
+
view.question ? /* @__PURE__ */ jsx(TextButton, { onClick: () => ui2({ kind: "dismiss" }), children: "Cancel" }) : null,
|
|
1017
|
+
view.question ? /* @__PURE__ */ jsx(TextButton, { strong: true, disabled: view.submitDisabled, onClick: () => ui2({ kind: "submit" }), children: view.submitLabel }) : null
|
|
1018
|
+
] })
|
|
876
1019
|
}
|
|
877
1020
|
),
|
|
878
|
-
|
|
879
|
-
"span",
|
|
880
|
-
{
|
|
881
|
-
style: {
|
|
882
|
-
fontSize: 9,
|
|
883
|
-
opacity: 0.6,
|
|
884
|
-
alignSelf: "flex-end",
|
|
885
|
-
// Over the limit the answer is REFUSED, not truncated — so the counter has to say
|
|
886
|
-
// so rather than implying the extra characters are merely ignored.
|
|
887
|
-
color: state.draftText.length > max ? "var(--xeno-danger)" : void 0
|
|
888
|
-
},
|
|
889
|
-
children: `${state.draftText.length} / ${max}`
|
|
890
|
-
}
|
|
891
|
-
) : null
|
|
1021
|
+
/* @__PURE__ */ jsx(StatusBar, { left: view.pendingLabel, right: view.expiryLabel })
|
|
892
1022
|
] }) : null
|
|
893
1023
|
] });
|
|
894
1024
|
}
|
|
@@ -979,16 +1109,22 @@ function createConsentPanel(options = {}) {
|
|
|
979
1109
|
}
|
|
980
1110
|
var consentPanel = createConsentPanel();
|
|
981
1111
|
export {
|
|
1112
|
+
BEHAVIOURS as CONSENT_BEHAVIOURS,
|
|
1113
|
+
CONSENT_DECLARATION,
|
|
982
1114
|
CONSENT_PANEL_ID,
|
|
1115
|
+
CONSENT_RUNTIME_UNITS,
|
|
983
1116
|
ConsentController,
|
|
984
1117
|
ConsentPanelView,
|
|
985
1118
|
ELICITATION_RESULT_SCHEMA,
|
|
986
1119
|
ELICITATION_SCHEMA,
|
|
987
1120
|
allowedDurations,
|
|
1121
|
+
applyConsentUi,
|
|
988
1122
|
autoCancel,
|
|
989
1123
|
autoDeny,
|
|
990
1124
|
consentManifest,
|
|
991
1125
|
consentPanel,
|
|
1126
|
+
consentViewManifest,
|
|
1127
|
+
consentViewState,
|
|
992
1128
|
createConsentPanel,
|
|
993
1129
|
effectiveRisk,
|
|
994
1130
|
elicitationAsk,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.15",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
66
66
|
"@xenosystem/block-sdk": ">=0.3.4 <1",
|
|
67
|
-
"@xenosystem/components": ">=0.
|
|
67
|
+
"@xenosystem/components": ">=0.25.0 <1",
|
|
68
68
|
"@xenosystem/data-core": "^0.1.0",
|
|
69
69
|
"@xenosystem/elements": ">=0.0.1",
|
|
70
70
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react": "^19.0.0",
|
|
82
82
|
"@types/react-dom": "^19.0.0",
|
|
83
83
|
"@xenosystem/block-sdk": "^0.3.4",
|
|
84
|
-
"@xenosystem/components": "^0.
|
|
84
|
+
"@xenosystem/components": "^0.25.0",
|
|
85
85
|
"@xenosystem/data-core": "^0.1.0",
|
|
86
86
|
"@xenosystem/elements": "0.0.1",
|
|
87
87
|
"@xenosystem/elements-react": "0.0.1",
|