@stigmer/react 3.0.7 → 3.0.8-dev.20260612062921

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.
Files changed (132) hide show
  1. package/access/ManageAccessButton.d.ts +47 -0
  2. package/access/ManageAccessButton.d.ts.map +1 -0
  3. package/access/ManageAccessButton.js +45 -0
  4. package/access/ManageAccessButton.js.map +1 -0
  5. package/access/ManageAccessDialog.d.ts +60 -0
  6. package/access/ManageAccessDialog.d.ts.map +1 -0
  7. package/access/ManageAccessDialog.js +83 -0
  8. package/access/ManageAccessDialog.js.map +1 -0
  9. package/access/index.d.ts +5 -0
  10. package/access/index.d.ts.map +1 -0
  11. package/access/index.js +7 -0
  12. package/access/index.js.map +1 -0
  13. package/access/types.d.ts +56 -0
  14. package/access/types.d.ts.map +1 -0
  15. package/access/types.js +2 -0
  16. package/access/types.js.map +1 -0
  17. package/access/useManageAccess.d.ts +60 -0
  18. package/access/useManageAccess.d.ts.map +1 -0
  19. package/access/useManageAccess.js +41 -0
  20. package/access/useManageAccess.js.map +1 -0
  21. package/agent/AgentDetailView.d.ts.map +1 -1
  22. package/agent/AgentDetailView.js +34 -4
  23. package/agent/AgentDetailView.js.map +1 -1
  24. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  25. package/agent-instance/AgentInstanceDetailPanel.js +14 -4
  26. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  27. package/iam-policy/GrantAccessForm.d.ts +15 -5
  28. package/iam-policy/GrantAccessForm.d.ts.map +1 -1
  29. package/iam-policy/GrantAccessForm.js +15 -12
  30. package/iam-policy/GrantAccessForm.js.map +1 -1
  31. package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
  32. package/iam-policy/OrgMembersPanel.js +2 -1
  33. package/iam-policy/OrgMembersPanel.js.map +1 -1
  34. package/iam-policy/PeopleWithAccess.d.ts +34 -0
  35. package/iam-policy/PeopleWithAccess.d.ts.map +1 -0
  36. package/iam-policy/PeopleWithAccess.js +55 -0
  37. package/iam-policy/PeopleWithAccess.js.map +1 -0
  38. package/iam-policy/PrincipalPicker.d.ts +48 -0
  39. package/iam-policy/PrincipalPicker.d.ts.map +1 -0
  40. package/iam-policy/PrincipalPicker.js +139 -0
  41. package/iam-policy/PrincipalPicker.js.map +1 -0
  42. package/iam-policy/ProviderBadge.d.ts +28 -0
  43. package/iam-policy/ProviderBadge.d.ts.map +1 -0
  44. package/iam-policy/ProviderBadge.js +31 -0
  45. package/iam-policy/ProviderBadge.js.map +1 -0
  46. package/iam-policy/SharePanel.d.ts +13 -5
  47. package/iam-policy/SharePanel.d.ts.map +1 -1
  48. package/iam-policy/SharePanel.js +9 -34
  49. package/iam-policy/SharePanel.js.map +1 -1
  50. package/iam-policy/index.d.ts +3 -0
  51. package/iam-policy/index.d.ts.map +1 -1
  52. package/iam-policy/index.js +3 -0
  53. package/iam-policy/index.js.map +1 -1
  54. package/index.d.ts +7 -5
  55. package/index.d.ts.map +1 -1
  56. package/index.js +6 -3
  57. package/index.js.map +1 -1
  58. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  59. package/mcp-server/McpServerDetailView.js +41 -12
  60. package/mcp-server/McpServerDetailView.js.map +1 -1
  61. package/organization/OrgProvider.d.ts +9 -0
  62. package/organization/OrgProvider.d.ts.map +1 -1
  63. package/organization/OrgProvider.js +12 -0
  64. package/organization/OrgProvider.js.map +1 -1
  65. package/organization/index.d.ts +1 -1
  66. package/organization/index.d.ts.map +1 -1
  67. package/organization/index.js +1 -1
  68. package/organization/index.js.map +1 -1
  69. package/package.json +12 -12
  70. package/skill/SkillDetailView.d.ts.map +1 -1
  71. package/skill/SkillDetailView.js +31 -3
  72. package/skill/SkillDetailView.js.map +1 -1
  73. package/src/access/ManageAccessButton.tsx +115 -0
  74. package/src/access/ManageAccessDialog.tsx +239 -0
  75. package/src/access/__tests__/ManageAccessButton.test.tsx +62 -0
  76. package/src/access/__tests__/ManageAccessDialog.test.tsx +146 -0
  77. package/src/access/index.ts +21 -0
  78. package/src/access/types.ts +58 -0
  79. package/src/access/useManageAccess.tsx +101 -0
  80. package/src/agent/AgentDetailView.tsx +50 -21
  81. package/src/agent-instance/AgentInstanceDetailPanel.tsx +24 -42
  82. package/src/iam-policy/GrantAccessForm.tsx +30 -35
  83. package/src/iam-policy/OrgMembersPanel.tsx +2 -0
  84. package/src/iam-policy/PeopleWithAccess.tsx +220 -0
  85. package/src/iam-policy/PrincipalPicker.tsx +347 -0
  86. package/src/iam-policy/ProviderBadge.tsx +53 -0
  87. package/src/iam-policy/SharePanel.tsx +20 -165
  88. package/src/iam-policy/index.ts +17 -0
  89. package/src/index.ts +30 -0
  90. package/src/mcp-server/McpServerDetailView.tsx +37 -9
  91. package/src/organization/OrgProvider.tsx +13 -0
  92. package/src/organization/index.ts +1 -1
  93. package/src/skill/SkillDetailView.tsx +34 -9
  94. package/src/workflow/WorkflowDetailView.tsx +49 -22
  95. package/src/workflow/WorkflowExecutionHeader.tsx +12 -1
  96. package/src/workflow/WorkflowExecutionViewer.tsx +8 -1
  97. package/src/workflow/index.ts +4 -0
  98. package/src/workflow/instance/RunVisibilityControl.tsx +116 -0
  99. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +55 -42
  100. package/src/workflow/instance/index.ts +5 -0
  101. package/src/workflow/instance/useUpdateWorkflowInstanceExecutionVisibility.ts +74 -0
  102. package/styles.css +1 -1
  103. package/workflow/WorkflowDetailView.d.ts.map +1 -1
  104. package/workflow/WorkflowDetailView.js +31 -3
  105. package/workflow/WorkflowDetailView.js.map +1 -1
  106. package/workflow/WorkflowExecutionHeader.d.ts +7 -0
  107. package/workflow/WorkflowExecutionHeader.d.ts.map +1 -1
  108. package/workflow/WorkflowExecutionHeader.js +2 -2
  109. package/workflow/WorkflowExecutionHeader.js.map +1 -1
  110. package/workflow/WorkflowExecutionViewer.d.ts +6 -1
  111. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  112. package/workflow/WorkflowExecutionViewer.js +2 -2
  113. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  114. package/workflow/index.d.ts +1 -1
  115. package/workflow/index.d.ts.map +1 -1
  116. package/workflow/index.js +1 -1
  117. package/workflow/index.js.map +1 -1
  118. package/workflow/instance/RunVisibilityControl.d.ts +25 -0
  119. package/workflow/instance/RunVisibilityControl.d.ts.map +1 -0
  120. package/workflow/instance/RunVisibilityControl.js +56 -0
  121. package/workflow/instance/RunVisibilityControl.js.map +1 -0
  122. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  123. package/workflow/instance/WorkflowInstanceDetailPanel.js +30 -4
  124. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  125. package/workflow/instance/index.d.ts +2 -0
  126. package/workflow/instance/index.d.ts.map +1 -1
  127. package/workflow/instance/index.js +2 -0
  128. package/workflow/instance/index.js.map +1 -1
  129. package/workflow/instance/useUpdateWorkflowInstanceExecutionVisibility.d.ts +30 -0
  130. package/workflow/instance/useUpdateWorkflowInstanceExecutionVisibility.d.ts.map +1 -0
  131. package/workflow/instance/useUpdateWorkflowInstanceExecutionVisibility.js +39 -0
  132. package/workflow/instance/useUpdateWorkflowInstanceExecutionVisibility.js.map +1 -0
@@ -0,0 +1,47 @@
1
+ import type { AccessResource, AccessVisibility, AccessExtraSection } from "./types";
2
+ /** Props for {@link ManageAccessButton}. */
3
+ export interface ManageAccessButtonProps {
4
+ /** The resource whose access is managed. */
5
+ readonly resource: AccessResource;
6
+ /** General access (visibility) axis; omit for resources without visibility. */
7
+ readonly visibility?: AccessVisibility;
8
+ /** Optional resource-specific section (e.g. run observability). */
9
+ readonly extraSection?: AccessExtraSection;
10
+ /** Button label. @default "Manage access" */
11
+ readonly label?: string;
12
+ /** Additional CSS classes for the trigger button. */
13
+ readonly className?: string;
14
+ }
15
+ /**
16
+ * The single drop-in, visible trigger for the unified Manage access dialog —
17
+ * used by surfaces that render a button in a header or panel (session and
18
+ * workflow-execution viewers, instance panels) rather than a kebab menu (those
19
+ * use {@link useManageAccess}).
20
+ *
21
+ * Self-gates on `can_view_access`: the button renders only for users who may
22
+ * see the access list, and the dialog's sections gate editing further. Because
23
+ * it lives in the SDK, web and desktop hosts stop re-implementing their own
24
+ * share buttons — one component, every host.
25
+ *
26
+ * All visual properties flow through `--stgm-*` design tokens.
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // A session has no visibility axis, so the dialog shows only People.
31
+ * <SessionViewer
32
+ * sessionId={id}
33
+ * headerActions={
34
+ * <ManageAccessButton
35
+ * resource={{
36
+ * kind: ApiResourceKind.session,
37
+ * kindString: "session",
38
+ * id,
39
+ * org: orgId,
40
+ * }}
41
+ * />
42
+ * }
43
+ * />
44
+ * ```
45
+ */
46
+ export declare function ManageAccessButton({ resource, visibility, extraSection, label, className, }: ManageAccessButtonProps): import("react/jsx-runtime").JSX.Element;
47
+ //# sourceMappingURL=ManageAccessButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManageAccessButton.d.ts","sourceRoot":"","sources":["../../src/access/ManageAccessButton.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAuB,EACvB,SAAS,GACV,EAAE,uBAAuB,2CA8BzB"}
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { PermissionGate } from "../iam-policy/PermissionGate";
6
+ import { ManageAccessDialog } from "./ManageAccessDialog";
7
+ /**
8
+ * The single drop-in, visible trigger for the unified Manage access dialog —
9
+ * used by surfaces that render a button in a header or panel (session and
10
+ * workflow-execution viewers, instance panels) rather than a kebab menu (those
11
+ * use {@link useManageAccess}).
12
+ *
13
+ * Self-gates on `can_view_access`: the button renders only for users who may
14
+ * see the access list, and the dialog's sections gate editing further. Because
15
+ * it lives in the SDK, web and desktop hosts stop re-implementing their own
16
+ * share buttons — one component, every host.
17
+ *
18
+ * All visual properties flow through `--stgm-*` design tokens.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * // A session has no visibility axis, so the dialog shows only People.
23
+ * <SessionViewer
24
+ * sessionId={id}
25
+ * headerActions={
26
+ * <ManageAccessButton
27
+ * resource={{
28
+ * kind: ApiResourceKind.session,
29
+ * kindString: "session",
30
+ * id,
31
+ * org: orgId,
32
+ * }}
33
+ * />
34
+ * }
35
+ * />
36
+ * ```
37
+ */
38
+ export function ManageAccessButton({ resource, visibility, extraSection, label = "Manage access", className, }) {
39
+ const [open, setOpen] = useState(false);
40
+ return (_jsxs(PermissionGate, { resource: { kind: resource.kindString, id: resource.id }, relation: "can_view_access", children: [_jsxs("button", { type: "button", onClick: () => setOpen(true), className: cn("inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium", "border border-border text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-2 focus:ring-ring", className), children: [_jsx(ShareIcon, {}), label] }), _jsx(ManageAccessDialog, { open: open, onOpenChange: setOpen, resource: resource, visibility: visibility, extraSection: extraSection })] }));
41
+ }
42
+ function ShareIcon() {
43
+ return (_jsxs("svg", { width: "13", height: "13", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "12", cy: "3.5", r: "1.75" }), _jsx("circle", { cx: "4", cy: "8", r: "1.75" }), _jsx("circle", { cx: "12", cy: "12.5", r: "1.75" }), _jsx("path", { d: "M5.5 7.1l5-2.7M5.5 8.9l5 2.7" })] }));
44
+ }
45
+ //# sourceMappingURL=ManageAccessButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManageAccessButton.js","sourceRoot":"","sources":["../../src/access/ManageAccessButton.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAqB1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,GAAG,eAAe,EACvB,SAAS,GACe;IACxB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,OAAO,CACL,MAAC,cAAc,IACb,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EACxD,QAAQ,EAAC,iBAAiB,aAE1B,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAC5B,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,4DAA4D,EAC5D,iDAAiD,EACjD,SAAS,CACV,aAED,KAAC,SAAS,KAAG,EACZ,KAAK,IACC,EACT,KAAC,kBAAkB,IACjB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,OAAO,EACrB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,GAC1B,IACa,CAClB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CACL,eACE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,KAAK,EACjB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,iBACV,MAAM,aAElB,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,KAAK,EAAC,CAAC,EAAC,MAAM,GAAG,EACpC,iBAAQ,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,MAAM,GAAG,EACjC,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,MAAM,EAAC,CAAC,EAAC,MAAM,GAAG,EACrC,eAAM,CAAC,EAAC,8BAA8B,GAAG,IACrC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type { AccessResource, AccessVisibility, AccessExtraSection } from "./types";
2
+ /** Props for {@link ManageAccessDialog}. */
3
+ export interface ManageAccessDialogProps {
4
+ /** Whether the dialog is open. */
5
+ readonly open: boolean;
6
+ /** Called when the dialog should open or close. */
7
+ readonly onOpenChange: (open: boolean) => void;
8
+ /** The resource whose access is managed. */
9
+ readonly resource: AccessResource;
10
+ /**
11
+ * General access (visibility) axis. Omit for resources without visibility
12
+ * (e.g. sessions, workflow executions).
13
+ */
14
+ readonly visibility?: AccessVisibility;
15
+ /**
16
+ * An optional resource-specific section appended below People (e.g.
17
+ * workflow-instance run observability).
18
+ */
19
+ readonly extraSection?: AccessExtraSection;
20
+ }
21
+ /**
22
+ * The one canonical "Manage access" dialog, mounted identically across every
23
+ * resource with a detail surface. Composes the platform's two access axes into
24
+ * a single Drive/GitHub-style modal: *General access* (visibility) over
25
+ * *People with access* (explicit grants), plus an optional resource-specific
26
+ * section.
27
+ *
28
+ * Each section renders only when it applies:
29
+ * - **General access** — only when {@link ManageAccessDialogProps.visibility}
30
+ * is provided. Delegates to {@link ResourceVisibilityControl}, which owns
31
+ * level selection and the `can_edit` gate.
32
+ * - **People with access** — only when the resource kind has grantable roles
33
+ * (`hasGrantableRoles`, proto-generated single source of truth). Delegates
34
+ * to {@link PeopleWithAccess}, which gates grant/revoke on `can_grant_access`.
35
+ * - **Extra section** — only when provided.
36
+ *
37
+ * The body mounts lazily (only while `open`) so its access-list fetch never
38
+ * fires on a closed dialog. Built on the native `<dialog>` element for focus
39
+ * trapping and escape handling, matching the SDK's modal convention. All
40
+ * visual properties flow through `--stgm-*` design tokens.
41
+ *
42
+ * Most hosts mount it indirectly via {@link ManageAccessButton} (a visible
43
+ * trigger) or {@link useManageAccess} (a kebab-menu action). Render it directly
44
+ * only when you own the open-state.
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * const [open, setOpen] = useState(false);
49
+ *
50
+ * // A blueprint has both axes: General access (visibility) over People.
51
+ * <ManageAccessDialog
52
+ * open={open}
53
+ * onOpenChange={setOpen}
54
+ * resource={{ kind: ApiResourceKind.agent, kindString: "agent", id, org, name }}
55
+ * visibility={{ kind: "agent", current: visibility, org, onChanged: refetch }}
56
+ * />
57
+ * ```
58
+ */
59
+ export declare function ManageAccessDialog({ open, onOpenChange, resource, visibility, extraSection, }: ManageAccessDialogProps): import("react/jsx-runtime").JSX.Element;
60
+ //# sourceMappingURL=ManageAccessDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManageAccessDialog.d.ts","sourceRoot":"","sources":["../../src/access/ManageAccessDialog.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,YAAY,GACb,EAAE,uBAAuB,2CA+HzB"}
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useRef } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { hasGrantableRoles } from "@stigmer/sdk";
6
+ import { PeopleWithAccess } from "../iam-policy/PeopleWithAccess";
7
+ import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
8
+ /**
9
+ * The one canonical "Manage access" dialog, mounted identically across every
10
+ * resource with a detail surface. Composes the platform's two access axes into
11
+ * a single Drive/GitHub-style modal: *General access* (visibility) over
12
+ * *People with access* (explicit grants), plus an optional resource-specific
13
+ * section.
14
+ *
15
+ * Each section renders only when it applies:
16
+ * - **General access** — only when {@link ManageAccessDialogProps.visibility}
17
+ * is provided. Delegates to {@link ResourceVisibilityControl}, which owns
18
+ * level selection and the `can_edit` gate.
19
+ * - **People with access** — only when the resource kind has grantable roles
20
+ * (`hasGrantableRoles`, proto-generated single source of truth). Delegates
21
+ * to {@link PeopleWithAccess}, which gates grant/revoke on `can_grant_access`.
22
+ * - **Extra section** — only when provided.
23
+ *
24
+ * The body mounts lazily (only while `open`) so its access-list fetch never
25
+ * fires on a closed dialog. Built on the native `<dialog>` element for focus
26
+ * trapping and escape handling, matching the SDK's modal convention. All
27
+ * visual properties flow through `--stgm-*` design tokens.
28
+ *
29
+ * Most hosts mount it indirectly via {@link ManageAccessButton} (a visible
30
+ * trigger) or {@link useManageAccess} (a kebab-menu action). Render it directly
31
+ * only when you own the open-state.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * const [open, setOpen] = useState(false);
36
+ *
37
+ * // A blueprint has both axes: General access (visibility) over People.
38
+ * <ManageAccessDialog
39
+ * open={open}
40
+ * onOpenChange={setOpen}
41
+ * resource={{ kind: ApiResourceKind.agent, kindString: "agent", id, org, name }}
42
+ * visibility={{ kind: "agent", current: visibility, org, onChanged: refetch }}
43
+ * />
44
+ * ```
45
+ */
46
+ export function ManageAccessDialog({ open, onOpenChange, resource, visibility, extraSection, }) {
47
+ const dialogRef = useRef(null);
48
+ const handleClose = useCallback(() => {
49
+ dialogRef.current?.close();
50
+ onOpenChange(false);
51
+ }, [onOpenChange]);
52
+ // Sync native dialog open state (matches the SDK dialog convention).
53
+ const prevOpenRef = useRef(false);
54
+ if (open !== prevOpenRef.current) {
55
+ prevOpenRef.current = open;
56
+ if (open) {
57
+ requestAnimationFrame(() => {
58
+ if (dialogRef.current && !dialogRef.current.open) {
59
+ dialogRef.current.showModal();
60
+ }
61
+ });
62
+ }
63
+ else if (dialogRef.current?.open) {
64
+ dialogRef.current.close();
65
+ }
66
+ }
67
+ const showPeople = hasGrantableRoles(resource.kind);
68
+ return (_jsx("dialog", { ref: dialogRef, onClose: handleClose, className: cn("fixed inset-0 m-auto w-full max-w-md rounded-xl border border-border bg-popover p-0 shadow-xl", "backdrop:bg-black/50"), "aria-labelledby": "manage-access-title", children: open && (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-start justify-between border-b border-border px-6 py-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { id: "manage-access-title", className: "text-base font-semibold text-foreground", children: "Manage access" }), resource.name && (_jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: resource.name }))] }), _jsx("button", { type: "button", onClick: handleClose, "aria-label": "Close", className: cn("rounded-md p-1 text-muted-foreground", "hover:text-foreground hover:bg-accent-hover", "focus:outline-none focus:ring-2 focus:ring-ring"), children: _jsx(CloseIcon, {}) })] }), _jsxs("div", { className: "flex flex-col divide-y divide-border", children: [visibility && (_jsx(AccessSection, { title: "General access", description: "Who can find and open this resource.", children: _jsx(ResourceVisibilityControl, { kind: visibility.kind, resourceId: resource.id, visibility: visibility.current, org: visibility.org, onChanged: visibility.onChanged }) })), showPeople && (_jsx(AccessSection, { title: "People with access", children: _jsx(PeopleWithAccess, { resource: {
69
+ kind: resource.kindString,
70
+ id: resource.id,
71
+ resourceKind: resource.kind,
72
+ }, resourceKindString: resource.kindString, resourceKind: resource.kind, orgId: resource.org }) })), extraSection && (_jsx(AccessSection, { title: extraSection.title, description: extraSection.description, children: extraSection.content }))] }), _jsx("div", { className: "flex items-center justify-end border-t border-border px-6 py-3", children: _jsx("button", { type: "button", onClick: handleClose, className: cn("rounded-md px-3 py-1.5 text-sm font-medium", "bg-primary text-primary-foreground hover:bg-primary-hover", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"), children: "Done" }) })] })) }));
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Internal section chrome
76
+ // ---------------------------------------------------------------------------
77
+ function AccessSection({ title, description, children, }) {
78
+ return (_jsxs("section", { className: "px-6 py-4", children: [_jsx("h3", { className: "text-xs font-medium text-muted-foreground", children: title }), description && (_jsx("p", { className: "mt-0.5 text-[0.65rem] text-muted-foreground", children: description })), _jsx("div", { className: "mt-2.5", children: children })] }));
79
+ }
80
+ function CloseIcon() {
81
+ return (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }));
82
+ }
83
+ //# sourceMappingURL=ManageAccessDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManageAccessDialog.js","sourceRoot":"","sources":["../../src/access/ManageAccessDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { ManageAccessDialog, type ManageAccessDialogProps, } from "./ManageAccessDialog";
2
+ export { ManageAccessButton, type ManageAccessButtonProps, } from "./ManageAccessButton";
3
+ export { useManageAccess, type UseManageAccessArgs, type UseManageAccessReturn, } from "./useManageAccess";
4
+ export type { AccessResource, AccessVisibility, AccessExtraSection, } from "./types";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/access/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,7 @@
1
+ // Access — the unified "Manage access" experience composing visibility
2
+ // (library) and explicit grants (iam-policy) into one dialog, with a kebab
3
+ // hook and a visible-button trigger for the surfaces that mount it.
4
+ export { ManageAccessDialog, } from "./ManageAccessDialog";
5
+ export { ManageAccessButton, } from "./ManageAccessButton";
6
+ export { useManageAccess, } from "./useManageAccess";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/access/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,2EAA2E;AAC3E,oEAAoE;AACpE,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,GAGhB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
3
+ import type { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
4
+ import type { VisibilityResourceKind } from "../library/useUpdateVisibility";
5
+ /**
6
+ * The resource whose access is being managed. Carries everything the People
7
+ * section needs: the enum {@link ApiResourceKind} (for grantable-role lookup),
8
+ * the FGA/API kind string (for IAM refs and permission checks), the id, and
9
+ * the owning org (drives the org-member typeahead).
10
+ */
11
+ export interface AccessResource {
12
+ /** ApiResourceKind enum — drives grantable-role lookup and capability. */
13
+ readonly kind: ApiResourceKind;
14
+ /** FGA/API kind string (e.g. "mcp_server", "session", "workflow_execution"). */
15
+ readonly kindString: string;
16
+ /** Resource id. */
17
+ readonly id: string;
18
+ /** Slug of the owning organization (`metadata.org`). */
19
+ readonly org: string;
20
+ /** Optional display name, shown as the dialog subtitle for context. */
21
+ readonly name?: string;
22
+ }
23
+ /**
24
+ * Describes the "General access" (visibility) axis for the Manage access
25
+ * dialog. Optional because not every resource has visibility (e.g. sessions
26
+ * and workflow executions do not). When present, the dialog renders the
27
+ * shared `ResourceVisibilityControl`, which owns level selection and
28
+ * the `can_edit` gate.
29
+ */
30
+ export interface AccessVisibility {
31
+ /** Resource kind, selecting both the updateVisibility RPC and FGA type. */
32
+ readonly kind: VisibilityResourceKind;
33
+ /** Current visibility of the resource. */
34
+ readonly current: ApiResourceVisibility;
35
+ /**
36
+ * Slug of the owning org (`metadata.org`); gates the Platform option for
37
+ * blueprints. Omit for instances and where Platform should not be offered.
38
+ */
39
+ readonly org?: string;
40
+ /** Called after a successful visibility change so the host can refetch. */
41
+ readonly onChanged?: () => void;
42
+ }
43
+ /**
44
+ * A generic, resource-specific access section appended below People — the
45
+ * escape hatch for the rare per-kind axis (today: workflow-instance run
46
+ * observability) without baking that knowledge into a generic dialog.
47
+ */
48
+ export interface AccessExtraSection {
49
+ /** Section heading. */
50
+ readonly title: string;
51
+ /** Optional one-line explanation under the heading. */
52
+ readonly description?: string;
53
+ /** The section body (e.g. a `<RunVisibilityControl />`). */
54
+ readonly content: ReactNode;
55
+ }
56
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAC3H,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AACpG,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mBAAmB;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ import { type ReactNode } from "react";
2
+ import type { DetailAction } from "../resource-detail/types";
3
+ import type { AccessResource, AccessVisibility, AccessExtraSection } from "./types";
4
+ /** Arguments for {@link useManageAccess}. */
5
+ export interface UseManageAccessArgs {
6
+ /**
7
+ * The resource whose access is managed, or `null` while it is still
8
+ * loading. When `null`, {@link UseManageAccessReturn.action} is `null` and
9
+ * the dialog renders nothing — safe to call before the resource is ready.
10
+ */
11
+ readonly resource: AccessResource | null;
12
+ /** General access (visibility) axis; omit for resources without visibility. */
13
+ readonly visibility?: AccessVisibility;
14
+ /** Optional resource-specific section (e.g. run observability). */
15
+ readonly extraSection?: AccessExtraSection;
16
+ /** Menu-item label. @default "Manage access" */
17
+ readonly label?: string;
18
+ }
19
+ /** Return value of {@link useManageAccess}. */
20
+ export interface UseManageAccessReturn {
21
+ /**
22
+ * A ready-to-spread {@link DetailAction} for a kebab/overflow menu, or
23
+ * `null` when the resource is unavailable or the user lacks
24
+ * `can_view_access`. Lives in the `"sharing"` group.
25
+ */
26
+ readonly action: DetailAction | null;
27
+ /** The {@link ManageAccessDialog} node — render it once in the host tree. */
28
+ readonly dialog: ReactNode;
29
+ /** Imperatively open the dialog. */
30
+ readonly open: () => void;
31
+ /** Whether the dialog is currently open. */
32
+ readonly isOpen: boolean;
33
+ }
34
+ /**
35
+ * Wires the unified Manage access dialog to a kebab/overflow menu — the
36
+ * trigger shape used by static resource detail views (agent, skill,
37
+ * mcp_server, workflow), whose actions live in {@link ResourceActionBar}'s
38
+ * menu rather than as a standalone button.
39
+ *
40
+ * Owns the open-state and the `can_view_access` gate (a viewer may open the
41
+ * dialog to read general access and the people list; the dialog's own sections
42
+ * gate editing). Returns a `null` action when the resource is still loading or
43
+ * the user cannot view access — so the host can unconditionally fold
44
+ * `action` into its actions array.
45
+ *
46
+ * Surfaces that want a *visible* trigger instead use {@link ManageAccessButton}.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const access = useManageAccess({
51
+ * resource: meta ? { kind: ApiResourceKind.agent, kindString: "agent", id: meta.id, org: meta.org } : null,
52
+ * visibility: meta ? { kind: "agent", current: meta.visibility, org: meta.org, onChanged: refetch } : undefined,
53
+ * });
54
+ * // ...
55
+ * <ResourceDetailShell actions={access.action ? [...actions, access.action] : actions} ... />
56
+ * {access.dialog}
57
+ * ```
58
+ */
59
+ export declare function useManageAccess({ resource, visibility, extraSection, label, }: UseManageAccessArgs): UseManageAccessReturn;
60
+ //# sourceMappingURL=useManageAccess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useManageAccess.d.ts","sourceRoot":"","sources":["../../src/access/useManageAccess.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAuB,GACxB,EAAE,mBAAmB,GAAG,qBAAqB,CA0B7C"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { useCheckPermission } from "../iam-policy/useCheckPermission";
5
+ import { ManageAccessDialog } from "./ManageAccessDialog";
6
+ /**
7
+ * Wires the unified Manage access dialog to a kebab/overflow menu — the
8
+ * trigger shape used by static resource detail views (agent, skill,
9
+ * mcp_server, workflow), whose actions live in {@link ResourceActionBar}'s
10
+ * menu rather than as a standalone button.
11
+ *
12
+ * Owns the open-state and the `can_view_access` gate (a viewer may open the
13
+ * dialog to read general access and the people list; the dialog's own sections
14
+ * gate editing). Returns a `null` action when the resource is still loading or
15
+ * the user cannot view access — so the host can unconditionally fold
16
+ * `action` into its actions array.
17
+ *
18
+ * Surfaces that want a *visible* trigger instead use {@link ManageAccessButton}.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const access = useManageAccess({
23
+ * resource: meta ? { kind: ApiResourceKind.agent, kindString: "agent", id: meta.id, org: meta.org } : null,
24
+ * visibility: meta ? { kind: "agent", current: meta.visibility, org: meta.org, onChanged: refetch } : undefined,
25
+ * });
26
+ * // ...
27
+ * <ResourceDetailShell actions={access.action ? [...actions, access.action] : actions} ... />
28
+ * {access.dialog}
29
+ * ```
30
+ */
31
+ export function useManageAccess({ resource, visibility, extraSection, label = "Manage access", }) {
32
+ const [isOpen, setIsOpen] = useState(false);
33
+ const { allowed: canView } = useCheckPermission(resource ? { kind: resource.kindString, id: resource.id } : null, "can_view_access");
34
+ const open = useCallback(() => setIsOpen(true), []);
35
+ const action = resource && canView
36
+ ? { id: "manage-access", label, group: "sharing", onAction: open }
37
+ : null;
38
+ const dialog = resource ? (_jsx(ManageAccessDialog, { open: isOpen, onOpenChange: setIsOpen, resource: resource, visibility: visibility, extraSection: extraSection })) : null;
39
+ return { action, dialog, open, isOpen };
40
+ }
41
+ //# sourceMappingURL=useManageAccess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useManageAccess.js","sourceRoot":"","sources":["../../src/access/useManageAccess.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAuC1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,GAAG,eAAe,GACH;IACpB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAC7C,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAChE,iBAAiB,CAClB,CAAC;IAEF,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpD,MAAM,MAAM,GACV,QAAQ,IAAI,OAAO;QACjB,CAAC,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;QAClE,CAAC,CAAC,IAAI,CAAC;IAEX,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CACxB,KAAC,kBAAkB,IACjB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,SAAS,EACvB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,GAC1B,CACH,CAAC,CAAC,CAAC,IAAI,CAAC;IAET,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AgentDetailView.d.ts","sourceRoot":"","sources":["../../src/agent/AgentDetailView.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4DAA4D,CAAC;AAShG,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAsB,MAAM,0BAA0B,CAAC;AAkBhG,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACrE;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,oDAAoD,EAAE,KAAK,KAAK,IAAI,CAAC;IACjH;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACzE;;OAEG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,OAAO,EACP,cAAc,EACd,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,GACV,EAAE,oBAAoB,2CAuKtB"}
1
+ {"version":3,"file":"AgentDetailView.d.ts","sourceRoot":"","sources":["../../src/agent/AgentDetailView.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4DAA4D,CAAC;AAWhG,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAsB,MAAM,0BAA0B,CAAC;AAkBhG,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACrE;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,oDAAoD,EAAE,KAAK,KAAK,IAAI,CAAC;IACjH;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACzE;;OAEG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,OAAO,EACP,cAAc,EACd,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,GACV,EAAE,oBAAoB,2CAkMtB"}
@@ -1,13 +1,15 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import { timestampDate } from "@bufbuild/protobuf/wkt";
6
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
6
7
  import { useAgent } from "./useAgent";
7
8
  import { useUpdateAgent } from "./useUpdateAgent";
8
9
  import { agentToInput } from "./internal/agentToInput";
9
10
  import { ErrorMessage } from "../error/ErrorMessage";
10
- import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
11
+ import { VisibilityBadge } from "../library/VisibilitySelector";
12
+ import { useManageAccess } from "../access/useManageAccess";
11
13
  import { ResourceDetailShell } from "../resource-detail/ResourceDetailShell";
12
14
  import { Section } from "../resource-detail/Section";
13
15
  import { useDetailTabs } from "../resource-detail/useDetailTabs";
@@ -112,6 +114,29 @@ export function AgentDetailView({ org, slug, onMcpServerClick, onSkillClick, onR
112
114
  onResourceLoadRef.current?.({ name: agent.metadata.name, id: agent.metadata.id });
113
115
  }
114
116
  }, [agent]);
117
+ // Unified Manage access — visibility (General access) over explicit grants
118
+ // (People), opened from the kebab. Derived from the loaded metadata, so the
119
+ // action stays null until the resource is ready (and folds harmlessly into
120
+ // the actions array meanwhile).
121
+ const access = useManageAccess({
122
+ resource: agent?.metadata
123
+ ? {
124
+ kind: ApiResourceKind.agent,
125
+ kindString: "agent",
126
+ id: agent.metadata.id,
127
+ org: agent.metadata.org,
128
+ name: agent.metadata.name,
129
+ }
130
+ : null,
131
+ visibility: agent?.metadata
132
+ ? {
133
+ kind: "agent",
134
+ current: agent.metadata.visibility,
135
+ org: agent.metadata.org,
136
+ onChanged: refetch,
137
+ }
138
+ : undefined,
139
+ });
115
140
  if (isLoading)
116
141
  return _jsx(LoadingSkeleton, { className: className });
117
142
  if (error)
@@ -135,7 +160,12 @@ export function AgentDetailView({ org, slug, onMcpServerClick, onSkillClick, onR
135
160
  createdAt: specAudit?.createdAt ? timestampDate(specAudit.createdAt) : null,
136
161
  updatedAt: specAudit?.updatedAt ? timestampDate(specAudit.updatedAt) : null,
137
162
  };
138
- const visibilityControl = meta ? (_jsx(ResourceVisibilityControl, { kind: "agent", resourceId: meta.id, visibility: meta.visibility, org: meta.org || org, onChanged: refetch })) : undefined;
163
+ // Inline visibility is read-only (at-a-glance); editing lives in the
164
+ // Manage access dialog, the single writer for both access axes.
165
+ const visibilityControl = meta ? (_jsx(VisibilityBadge, { visibility: meta.visibility })) : undefined;
166
+ const mergedActions = access.action
167
+ ? [...(actions ?? []), access.action]
168
+ : actions;
139
169
  let tabContent;
140
170
  if (activeAdditionalTab) {
141
171
  tabContent = activeAdditionalTab.content;
@@ -149,7 +179,7 @@ export function AgentDetailView({ org, slug, onMcpServerClick, onSkillClick, onR
149
179
  else {
150
180
  tabContent = (_jsx(AgentOverview, { spec: spec, agentOrg: agentOrg, description: spec?.description, onMcpServerClick: onMcpServerClick, onSkillClick: onSkillClick, editable: editable, isSaving: isUpdating, saveField: saveField }));
151
181
  }
152
- return (_jsx(ResourceDetailShell, { header: headerMeta, visibilityControl: visibilityControl, primaryAction: primaryAction, actions: actions, tabs: effectiveTabs, activeTab: effectiveTabs ? effectiveActiveTab : undefined, onTabChange: effectiveTabs ? effectiveOnTabChange : undefined, tabsAriaLabel: "Agent detail sections", className: className, children: tabContent }));
182
+ return (_jsxs(_Fragment, { children: [_jsx(ResourceDetailShell, { header: headerMeta, visibilityControl: visibilityControl, primaryAction: primaryAction, actions: mergedActions, tabs: effectiveTabs, activeTab: effectiveTabs ? effectiveActiveTab : undefined, onTabChange: effectiveTabs ? effectiveOnTabChange : undefined, tabsAriaLabel: "Agent detail sections", className: className, children: tabContent }), access.dialog] }));
153
183
  }
154
184
  // ---------------------------------------------------------------------------
155
185
  // Overview content — the agent's configuration sections