@stigmer/react 3.1.13 → 3.1.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.
Files changed (139) hide show
  1. package/agent/AgentDetailView.d.ts +9 -9
  2. package/agent/AgentDetailView.d.ts.map +1 -1
  3. package/agent/AgentDetailView.js +23 -31
  4. package/agent/AgentDetailView.js.map +1 -1
  5. package/agent-instance/AgentInstanceEmptyState.d.ts +4 -1
  6. package/agent-instance/AgentInstanceEmptyState.d.ts.map +1 -1
  7. package/agent-instance/AgentInstanceEmptyState.js +12 -5
  8. package/agent-instance/AgentInstanceEmptyState.js.map +1 -1
  9. package/agent-instance/AgentInstanceList.d.ts +13 -2
  10. package/agent-instance/AgentInstanceList.d.ts.map +1 -1
  11. package/agent-instance/AgentInstanceList.js +8 -4
  12. package/agent-instance/AgentInstanceList.js.map +1 -1
  13. package/agent-instance/useAgentInstances.d.ts +10 -3
  14. package/agent-instance/useAgentInstances.d.ts.map +1 -1
  15. package/agent-instance/useAgentInstances.js +12 -4
  16. package/agent-instance/useAgentInstances.js.map +1 -1
  17. package/button/Button.d.ts +54 -0
  18. package/button/Button.d.ts.map +1 -0
  19. package/button/Button.js +42 -0
  20. package/button/Button.js.map +1 -0
  21. package/button/index.d.ts +3 -0
  22. package/button/index.d.ts.map +1 -0
  23. package/button/index.js +2 -0
  24. package/button/index.js.map +1 -0
  25. package/empty-state/EmptyState.d.ts.map +1 -1
  26. package/empty-state/EmptyState.js +8 -3
  27. package/empty-state/EmptyState.js.map +1 -1
  28. package/empty-state/types.d.ts +2 -0
  29. package/empty-state/types.d.ts.map +1 -1
  30. package/execution/index.d.ts +1 -1
  31. package/execution/index.d.ts.map +1 -1
  32. package/execution/index.js.map +1 -1
  33. package/execution/useCreateAgentExecution.d.ts +81 -9
  34. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  35. package/execution/useCreateAgentExecution.js +42 -4
  36. package/execution/useCreateAgentExecution.js.map +1 -1
  37. package/index.d.ts +5 -3
  38. package/index.d.ts.map +1 -1
  39. package/index.js +4 -2
  40. package/index.js.map +1 -1
  41. package/package.json +4 -4
  42. package/session/useNewSessionFlow.d.ts +6 -3
  43. package/session/useNewSessionFlow.d.ts.map +1 -1
  44. package/session/useNewSessionFlow.js +34 -35
  45. package/session/useNewSessionFlow.js.map +1 -1
  46. package/sharing/AgentShareList.d.ts +46 -0
  47. package/sharing/AgentShareList.d.ts.map +1 -0
  48. package/sharing/AgentShareList.js +159 -0
  49. package/sharing/AgentShareList.js.map +1 -0
  50. package/sharing/ShareAgentDialog.d.ts +38 -25
  51. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  52. package/sharing/ShareAgentDialog.js +131 -62
  53. package/sharing/ShareAgentDialog.js.map +1 -1
  54. package/sharing/index.d.ts +10 -8
  55. package/sharing/index.d.ts.map +1 -1
  56. package/sharing/index.js +5 -4
  57. package/sharing/index.js.map +1 -1
  58. package/sharing/useAgentShares.d.ts +48 -0
  59. package/sharing/useAgentShares.d.ts.map +1 -0
  60. package/sharing/useAgentShares.js +44 -0
  61. package/sharing/useAgentShares.js.map +1 -0
  62. package/sharing/useCanCreateAgentShare.d.ts +43 -0
  63. package/sharing/useCanCreateAgentShare.d.ts.map +1 -0
  64. package/sharing/useCanCreateAgentShare.js +44 -0
  65. package/sharing/useCanCreateAgentShare.js.map +1 -0
  66. package/sharing/useDeleteAgentShare.d.ts +42 -0
  67. package/sharing/useDeleteAgentShare.d.ts.map +1 -0
  68. package/sharing/useDeleteAgentShare.js +45 -0
  69. package/sharing/useDeleteAgentShare.js.map +1 -0
  70. package/sharing/useSaveAgentShare.d.ts +43 -18
  71. package/sharing/useSaveAgentShare.d.ts.map +1 -1
  72. package/sharing/useSaveAgentShare.js +55 -22
  73. package/sharing/useSaveAgentShare.js.map +1 -1
  74. package/src/agent/AgentDetailView.tsx +37 -43
  75. package/src/agent-instance/AgentInstanceEmptyState.tsx +24 -43
  76. package/src/agent-instance/AgentInstanceList.tsx +29 -16
  77. package/src/agent-instance/__tests__/agent-instance-hooks.test.tsx +19 -0
  78. package/src/agent-instance/useAgentInstances.ts +12 -3
  79. package/src/button/Button.tsx +104 -0
  80. package/src/button/__tests__/Button.test.tsx +82 -0
  81. package/src/button/index.ts +2 -0
  82. package/src/empty-state/EmptyState.tsx +8 -10
  83. package/src/empty-state/types.ts +2 -0
  84. package/src/execution/__tests__/useCreateAgentExecution.test.tsx +92 -0
  85. package/src/execution/index.ts +2 -0
  86. package/src/execution/useCreateAgentExecution.ts +116 -10
  87. package/src/index.ts +17 -9
  88. package/src/session/__tests__/useNewSessionFlow.test.tsx +121 -52
  89. package/src/session/useNewSessionFlow.ts +38 -37
  90. package/src/sharing/AgentShareList.tsx +502 -0
  91. package/src/sharing/ShareAgentDialog.tsx +310 -112
  92. package/src/sharing/__tests__/AgentShareList.test.tsx +388 -0
  93. package/src/sharing/__tests__/ShareAgentDialog.test.tsx +311 -312
  94. package/src/sharing/__tests__/useAgentShares.test.tsx +186 -0
  95. package/src/sharing/__tests__/useCanCreateAgentShare.test.tsx +190 -0
  96. package/src/sharing/index.ts +10 -12
  97. package/src/sharing/useAgentShares.ts +74 -0
  98. package/src/sharing/useCanCreateAgentShare.ts +74 -0
  99. package/src/sharing/useDeleteAgentShare.ts +73 -0
  100. package/src/sharing/useSaveAgentShare.ts +73 -23
  101. package/src/workflow/WorkflowDetailView.tsx +9 -0
  102. package/src/workflow/instance/WorkflowInstanceEmptyState.tsx +24 -43
  103. package/src/workflow/instance/WorkflowInstanceList.tsx +29 -16
  104. package/src/workflow/useWorkflowInstances.ts +10 -3
  105. package/styles.css +1 -1
  106. package/workflow/WorkflowDetailView.d.ts +8 -1
  107. package/workflow/WorkflowDetailView.d.ts.map +1 -1
  108. package/workflow/WorkflowDetailView.js +2 -2
  109. package/workflow/WorkflowDetailView.js.map +1 -1
  110. package/workflow/instance/WorkflowInstanceEmptyState.d.ts +4 -1
  111. package/workflow/instance/WorkflowInstanceEmptyState.d.ts.map +1 -1
  112. package/workflow/instance/WorkflowInstanceEmptyState.js +12 -5
  113. package/workflow/instance/WorkflowInstanceEmptyState.js.map +1 -1
  114. package/workflow/instance/WorkflowInstanceList.d.ts +13 -2
  115. package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
  116. package/workflow/instance/WorkflowInstanceList.js +8 -4
  117. package/workflow/instance/WorkflowInstanceList.js.map +1 -1
  118. package/workflow/useWorkflowInstances.d.ts +8 -3
  119. package/workflow/useWorkflowInstances.d.ts.map +1 -1
  120. package/workflow/useWorkflowInstances.js +10 -4
  121. package/workflow/useWorkflowInstances.js.map +1 -1
  122. package/sharing/useAgentShare.d.ts +0 -49
  123. package/sharing/useAgentShare.d.ts.map +0 -1
  124. package/sharing/useAgentShare.js +0 -64
  125. package/sharing/useAgentShare.js.map +0 -1
  126. package/sharing/useCreateExternalShareLink.d.ts +0 -90
  127. package/sharing/useCreateExternalShareLink.d.ts.map +0 -1
  128. package/sharing/useCreateExternalShareLink.js +0 -65
  129. package/sharing/useCreateExternalShareLink.js.map +0 -1
  130. package/sharing/useShareAgent.d.ts +0 -69
  131. package/sharing/useShareAgent.d.ts.map +0 -1
  132. package/sharing/useShareAgent.js +0 -42
  133. package/sharing/useShareAgent.js.map +0 -1
  134. package/src/sharing/__tests__/useAgentShare.test.tsx +0 -210
  135. package/src/sharing/__tests__/useCreateExternalShareLink.test.tsx +0 -194
  136. package/src/sharing/__tests__/useShareAgent.test.tsx +0 -131
  137. package/src/sharing/useAgentShare.ts +0 -105
  138. package/src/sharing/useCreateExternalShareLink.tsx +0 -141
  139. package/src/sharing/useShareAgent.tsx +0 -107
@@ -0,0 +1,82 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { render, screen, cleanup } from "@testing-library/react";
3
+ import { Button } from "../Button";
4
+
5
+ afterEach(cleanup);
6
+
7
+ describe("Button", () => {
8
+ it("renders a native button with the label and fires onClick", () => {
9
+ const onClick = vi.fn();
10
+ render(<Button onClick={onClick}>Create share</Button>);
11
+
12
+ const el = screen.getByRole("button", { name: "Create share" });
13
+ expect(el.tagName).toBe("BUTTON");
14
+ el.click();
15
+ expect(onClick).toHaveBeenCalledTimes(1);
16
+ });
17
+
18
+ it("defaults type to button so it never submits an enclosing form", () => {
19
+ render(<Button>Save</Button>);
20
+ expect(screen.getByRole("button").getAttribute("type")).toBe("button");
21
+ });
22
+
23
+ it("allows an explicit type override", () => {
24
+ render(<Button type="submit">Submit</Button>);
25
+ expect(screen.getByRole("button").getAttribute("type")).toBe("submit");
26
+ });
27
+
28
+ it("applies the variant's token classes", () => {
29
+ const { rerender } = render(<Button>CTA</Button>);
30
+ const el = screen.getByRole("button");
31
+ expect(el.className).toContain("bg-primary");
32
+
33
+ rerender(<Button variant="outline">CTA</Button>);
34
+ expect(el.className).toContain("border-border");
35
+ expect(el.className).not.toContain("bg-primary");
36
+
37
+ rerender(<Button variant="ghost">CTA</Button>);
38
+ expect(el.className).toContain("hover:bg-accent-hover");
39
+
40
+ rerender(<Button variant="destructive">CTA</Button>);
41
+ expect(el.className).toContain("bg-destructive");
42
+ });
43
+
44
+ it("applies the size classes", () => {
45
+ const { rerender } = render(<Button size="xs">CTA</Button>);
46
+ const el = screen.getByRole("button");
47
+ expect(el.className).toContain("px-2.5");
48
+
49
+ rerender(<Button size="sm">CTA</Button>);
50
+ expect(el.className).toContain("px-3");
51
+ });
52
+
53
+ it("renders a leading icon before the label", () => {
54
+ render(
55
+ <Button icon={<svg data-testid="icon" aria-hidden="true" />}>
56
+ Create instance
57
+ </Button>,
58
+ );
59
+
60
+ const el = screen.getByRole("button", { name: "Create instance" });
61
+ expect(el.firstElementChild).toBe(screen.getByTestId("icon"));
62
+ });
63
+
64
+ it("passes native attributes through (disabled, aria-label)", () => {
65
+ const onClick = vi.fn();
66
+ render(
67
+ <Button disabled aria-label="Reset link" onClick={onClick}>
68
+ Reset
69
+ </Button>,
70
+ );
71
+
72
+ const el = screen.getByRole("button", { name: "Reset link" });
73
+ expect(el.hasAttribute("disabled")).toBe(true);
74
+ el.click();
75
+ expect(onClick).not.toHaveBeenCalled();
76
+ });
77
+
78
+ it("merges caller classes after the variant classes", () => {
79
+ render(<Button className="mt-2">CTA</Button>);
80
+ expect(screen.getByRole("button").className).toContain("mt-2");
81
+ });
82
+ });
@@ -0,0 +1,2 @@
1
+ export { Button } from "./Button.js";
2
+ export type { ButtonProps, ButtonSize, ButtonVariant } from "./Button.js";
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { cn } from "@stigmer/theme";
4
+ import { Button } from "../button/Button.js";
4
5
  import { useEmptyState } from "./useEmptyState.js";
5
6
  import type { EmptyStateProps } from "./types.js";
6
7
 
@@ -71,19 +72,16 @@ export function EmptyState({
71
72
  {children
72
73
  ? <div className="mt-1">{children}</div>
73
74
  : action && (
74
- <button
75
- type="button"
75
+ <Button
76
+ // A retry after an error is a recovery affordance, not the
77
+ // view's call to action — outline keeps it appropriately quiet.
78
+ variant={variant === "error" ? "outline" : "primary"}
79
+ icon={action.icon}
76
80
  onClick={action.onClick}
77
- className={cn(
78
- "mt-1 inline-flex items-center rounded-md px-3 py-1.5 text-xs font-medium",
79
- variant === "error"
80
- ? "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground"
81
- : "bg-primary text-primary-foreground hover:bg-primary-hover",
82
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
83
- )}
81
+ className="mt-1"
84
82
  >
85
83
  {action.label}
86
- </button>
84
+ </Button>
87
85
  )}
88
86
  </div>
89
87
  );
@@ -16,6 +16,8 @@ export interface EmptyStateAction {
16
16
  readonly label: string;
17
17
  /** Click handler. */
18
18
  readonly onClick: () => void;
19
+ /** Optional leading icon (e.g. a plus glyph on create CTAs). */
20
+ readonly icon?: ReactNode;
19
21
  }
20
22
 
21
23
  /** Options for the {@link useEmptyState} behavior hook. */
@@ -3,6 +3,7 @@ import { renderHook, act } from "@testing-library/react";
3
3
  import type { ReactNode } from "react";
4
4
  import type { Stigmer } from "@stigmer/sdk";
5
5
  import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
6
+ import { Harness, ExecutionTarget } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
6
7
  import { StigmerContext } from "../../context";
7
8
  import { useCreateAgentExecution } from "../useCreateAgentExecution";
8
9
 
@@ -84,6 +85,97 @@ describe("useCreateAgentExecution — executionConfig mapping", () => {
84
85
  });
85
86
  });
86
87
 
88
+ describe("useCreateAgentExecution — one-call session bootstrap (sessionSpec)", () => {
89
+ it("converts harness and executionTarget options to proto enums", async () => {
90
+ const { result } = renderHook(() => useCreateAgentExecution(), {
91
+ wrapper: createWrapper(makeMockClient()),
92
+ });
93
+
94
+ await act(async () => {
95
+ await result.current.create({
96
+ org: "acme",
97
+ message: "Customize the landing page",
98
+ sessionSpec: {
99
+ agentInstanceId: "ain-1",
100
+ workspaceEntries: [
101
+ { name: "site", source: { localPath: { path: "/repos/site" } } },
102
+ ],
103
+ harness: "native",
104
+ executionTarget: "local",
105
+ },
106
+ });
107
+ });
108
+
109
+ expect(mockCreate).toHaveBeenCalledTimes(1);
110
+ const input = mockCreate.mock.calls[0][0];
111
+ expect(input.sessionId).toBeUndefined();
112
+ expect(input.sessionSpec).toMatchObject({
113
+ agentInstanceId: "ain-1",
114
+ harness: Harness.NATIVE,
115
+ executionTarget: ExecutionTarget.LOCAL,
116
+ });
117
+ expect(input.sessionSpec.workspaceEntries).toEqual([
118
+ { name: "site", source: { localPath: { path: "/repos/site" } } },
119
+ ]);
120
+ });
121
+
122
+ it("leaves harness and executionTarget undefined when not chosen (server decides)", async () => {
123
+ const { result } = renderHook(() => useCreateAgentExecution(), {
124
+ wrapper: createWrapper(makeMockClient()),
125
+ });
126
+
127
+ await act(async () => {
128
+ await result.current.create({
129
+ org: "acme",
130
+ message: "Hello",
131
+ sessionSpec: { agentInstanceId: "ain-1" },
132
+ });
133
+ });
134
+
135
+ const input = mockCreate.mock.calls[0][0];
136
+ expect(input.sessionSpec.harness).toBeUndefined();
137
+ expect(input.sessionSpec.executionTarget).toBeUndefined();
138
+ });
139
+
140
+ it("returns the server-assigned session id from the bootstrap response", async () => {
141
+ mockCreate.mockResolvedValueOnce({
142
+ metadata: { id: "aex-1" },
143
+ spec: { sessionId: "ses-created" },
144
+ });
145
+ const { result } = renderHook(() => useCreateAgentExecution(), {
146
+ wrapper: createWrapper(makeMockClient()),
147
+ });
148
+
149
+ let created: { executionId: string; sessionId: string } | undefined;
150
+ await act(async () => {
151
+ created = await result.current.create({
152
+ org: "acme",
153
+ message: "Hello",
154
+ sessionSpec: { agentInstanceId: "ain-1" },
155
+ });
156
+ });
157
+
158
+ expect(created).toEqual({ executionId: "aex-1", sessionId: "ses-created" });
159
+ });
160
+
161
+ it("echoes the input session id on the existing-session path", async () => {
162
+ const { result } = renderHook(() => useCreateAgentExecution(), {
163
+ wrapper: createWrapper(makeMockClient()),
164
+ });
165
+
166
+ let created: { executionId: string; sessionId: string } | undefined;
167
+ await act(async () => {
168
+ created = await result.current.create({
169
+ org: "acme",
170
+ sessionId: "ses-1",
171
+ message: "Hello",
172
+ });
173
+ });
174
+
175
+ expect(created).toEqual({ executionId: "aex-1", sessionId: "ses-1" });
176
+ });
177
+ });
178
+
87
179
  describe("useCreateAgentExecution — supersede link (edit-and-resubmit)", () => {
88
180
  it("maps supersedesExecutionId into the create call", async () => {
89
181
  const { result } = renderHook(() => useCreateAgentExecution(), {
@@ -1,7 +1,9 @@
1
1
  export { useCreateAgentExecution } from "./useCreateAgentExecution.js";
2
2
  export type {
3
+ BootstrapSessionSpec,
3
4
  CreateAgentExecutionInput,
4
5
  CreateAgentExecutionResult,
6
+ SharedAgentExecutionFields,
5
7
  UseCreateAgentExecutionReturn,
6
8
  } from "./useCreateAgentExecution.js";
7
9
 
@@ -2,17 +2,55 @@
2
2
 
3
3
  import { useCallback, useState } from "react";
4
4
  import type { JsonObject } from "@bufbuild/protobuf";
5
- import type { AttachmentInput, EnvVarInput } from "@stigmer/sdk";
5
+ import type {
6
+ AttachmentInput,
7
+ EnvVarInput,
8
+ McpServerUsageInput,
9
+ ResourceRef,
10
+ WorkspaceEntryInput,
11
+ } from "@stigmer/sdk";
6
12
  import { useStigmer } from "../hooks.js";
7
13
  import { toError } from "../internal/toError.js";
8
14
  import { toProtoInteractionMode } from "../composer/interaction-mode.js";
15
+ import { toProtoHarness, type HarnessOption } from "../models/harness.js";
16
+ import {
17
+ toProtoExecutionTarget,
18
+ type ExecutionTargetOption,
19
+ } from "../session/execution-target.js";
9
20
 
10
- /** Input for {@link UseCreateAgentExecutionReturn.create}. */
11
- export interface CreateAgentExecutionInput {
21
+ /**
22
+ * Spec for the session the server auto-creates on the one-call bootstrap
23
+ * path (maps to `AgentExecutionSpec.session_spec` in the proto).
24
+ *
25
+ * Carries the session shape — workspace, harness, execution target, MCP
26
+ * servers, skills — alongside the first message, so starting a session
27
+ * with a configured workspace is a single API call (stigmer/stigmer#249).
28
+ *
29
+ * When `agentInstanceId` is omitted, the server resolves the agent's
30
+ * default instance from the execution's `agentId` (creating the instance
31
+ * if missing), or falls back to the platform default agent.
32
+ */
33
+ export interface BootstrapSessionSpec {
34
+ /** Agent instance the session runs against. Omit to let the server resolve it. */
35
+ readonly agentInstanceId?: string;
36
+ /** Initial conversation subject. Omit for an async LLM-generated title. */
37
+ readonly subject?: string;
38
+ /** Workspace source entries to attach to the session. */
39
+ readonly workspaceEntries?: WorkspaceEntryInput[];
40
+ /** MCP server configurations to include for tool access. */
41
+ readonly mcpServerUsages?: McpServerUsageInput[];
42
+ /** Skill references to enable for executions in this session. */
43
+ readonly skillRefs?: ResourceRef[];
44
+ /** Execution harness. Immutable after the first execution runs. */
45
+ readonly harness?: HarnessOption;
46
+ /** Where session activities execute. Immutable after the first execution runs. */
47
+ readonly executionTarget?: ExecutionTargetOption;
48
+ }
49
+
50
+ /** Fields shared by both variants of {@link CreateAgentExecutionInput}. */
51
+ export interface SharedAgentExecutionFields {
12
52
  /** Organization slug that owns the session. */
13
53
  readonly org: string;
14
- /** Session to create the execution within. */
15
- readonly sessionId: string;
16
54
  /** User message that initiates the execution. */
17
55
  readonly message: string;
18
56
  /** Override the default model for this execution. */
@@ -106,11 +144,42 @@ export interface CreateAgentExecutionInput {
106
144
  readonly supersedesExecutionId?: string;
107
145
  }
108
146
 
147
+ /**
148
+ * Input for {@link UseCreateAgentExecutionReturn.create}. Exactly one
149
+ * session strategy must be provided:
150
+ *
151
+ * - **`sessionId`** — Create the execution within an existing session.
152
+ * - **`sessionSpec`** — One-call bootstrap: the server creates a session
153
+ * from the embedded spec and dispatches this execution in it. The new
154
+ * session's ID is returned on {@link CreateAgentExecutionResult.sessionId}.
155
+ *
156
+ * Providing both is a type error (and an `INVALID_ARGUMENT` server-side).
157
+ */
158
+ export type CreateAgentExecutionInput = SharedAgentExecutionFields &
159
+ (
160
+ | {
161
+ /** Session to create the execution within. */
162
+ readonly sessionId: string;
163
+ /** @internal Discriminant — excluded when `sessionId` is provided. */
164
+ readonly sessionSpec?: never;
165
+ }
166
+ | {
167
+ /** Spec for the session to auto-create (one-call bootstrap). */
168
+ readonly sessionSpec: BootstrapSessionSpec;
169
+ /** @internal Discriminant — excluded when `sessionSpec` is provided. */
170
+ readonly sessionId?: never;
171
+ }
172
+ );
173
+
109
174
  /** Resolved output of {@link UseCreateAgentExecutionReturn.create}. */
110
175
  export interface CreateAgentExecutionResult {
111
176
  /** Server-assigned identifier for the newly created execution. */
112
177
  readonly executionId: string;
113
- /** Session the execution belongs to (echoed from input). */
178
+ /**
179
+ * Session the execution belongs to. On the `sessionId` path this echoes
180
+ * the input; on the `sessionSpec` bootstrap path it is the server-created
181
+ * session's ID.
182
+ */
114
183
  readonly sessionId: string;
115
184
  }
116
185
 
@@ -132,9 +201,12 @@ export interface UseCreateAgentExecutionReturn {
132
201
  * Behavior hook that wraps `agentExecution.create()` with loading/error
133
202
  * state.
134
203
  *
135
- * Maps 1:1 to the AgentExecution aggregate — a single run of an agent
136
- * within an existing session. Requires a `sessionId`; use
137
- * {@link useCreateSession} to create the session first.
204
+ * Maps 1:1 to the AgentExecution aggregate — a single run of an agent.
205
+ * Two session strategies are supported, mirroring the RPC contract:
206
+ * pass `sessionId` to execute within an existing session (use
207
+ * {@link useCreateSession} to create one), or pass `sessionSpec` to
208
+ * bootstrap a new session (workspace, harness, execution target) and
209
+ * dispatch the first message in a single call.
138
210
  *
139
211
  * Supports both secret delivery flows:
140
212
  *
@@ -165,6 +237,21 @@ export interface UseCreateAgentExecutionReturn {
165
237
  * },
166
238
  * });
167
239
  * ```
240
+ *
241
+ * @example
242
+ * ```tsx
243
+ * // One-call bootstrap: session with a workspace + first message
244
+ * const { create } = useCreateAgentExecution();
245
+ * const { sessionId } = await create({
246
+ * org: "acme",
247
+ * message: "Customize the landing page",
248
+ * sessionSpec: {
249
+ * agentInstanceId: "ain_abc",
250
+ * workspaceEntries: [{ name: "site", source: { localPath: { path: "/repos/site" } } }],
251
+ * executionTarget: "local",
252
+ * },
253
+ * });
254
+ * ```
168
255
  */
169
256
  export function useCreateAgentExecution(): UseCreateAgentExecutionReturn {
170
257
  const stigmer = useStigmer();
@@ -199,10 +286,27 @@ export function useCreateAgentExecution(): UseCreateAgentExecutionReturn {
199
286
  }
200
287
  : undefined;
201
288
 
289
+ const sessionSpec = input.sessionSpec
290
+ ? {
291
+ agentInstanceId: input.sessionSpec.agentInstanceId,
292
+ subject: input.sessionSpec.subject,
293
+ workspaceEntries: input.sessionSpec.workspaceEntries,
294
+ mcpServerUsages: input.sessionSpec.mcpServerUsages,
295
+ skillRefs: input.sessionSpec.skillRefs,
296
+ harness: input.sessionSpec.harness
297
+ ? toProtoHarness(input.sessionSpec.harness)
298
+ : undefined,
299
+ executionTarget: input.sessionSpec.executionTarget
300
+ ? toProtoExecutionTarget(input.sessionSpec.executionTarget)
301
+ : undefined,
302
+ }
303
+ : undefined;
304
+
202
305
  const execution = await stigmer.agentExecution.create({
203
306
  name: `execution-${Date.now()}`,
204
307
  org: input.org,
205
308
  sessionId: input.sessionId,
309
+ sessionSpec,
206
310
  agentId: input.agentId,
207
311
  message: input.message,
208
312
  executionConfig,
@@ -215,7 +319,9 @@ export function useCreateAgentExecution(): UseCreateAgentExecutionReturn {
215
319
 
216
320
  return {
217
321
  executionId: execution.metadata!.id,
218
- sessionId: input.sessionId,
322
+ // On the bootstrap path the server assigns the session; trust the
323
+ // response first so both variants report the real session.
324
+ sessionId: execution.spec?.sessionId ?? input.sessionId ?? "",
219
325
  };
220
326
  } catch (err) {
221
327
  setError(toError(err));
package/src/index.ts CHANGED
@@ -336,8 +336,10 @@ export {
336
336
  getArtifactRenderMode,
337
337
  } from "./execution/index.js";
338
338
  export type {
339
+ BootstrapSessionSpec,
339
340
  CreateAgentExecutionInput,
340
341
  CreateAgentExecutionResult,
342
+ SharedAgentExecutionFields,
341
343
  UseCreateAgentExecutionReturn,
342
344
  UseExecutionStreamReturn,
343
345
  UseAgentExecutionActionsOptions,
@@ -985,17 +987,19 @@ export type {
985
987
  } from "./invitation/index.js";
986
988
 
987
989
  // Sharing — shared-agent public profile, the anonymous-visitor chat organism,
988
- // and the owner-side Share experience (dialog, kebab hook, AgentShare hooks).
990
+ // and the owner-side Share experience (Shares tab list, dialog, AgentShare hooks).
989
991
  export {
990
992
  useSharedAgentProfile,
991
993
  SharedAgentChat,
994
+ draftFromShare,
992
995
  sharingAudienceFromProto,
993
- useAgentShare,
996
+ useAgentShares,
997
+ useCanCreateAgentShare,
994
998
  useSaveAgentShare,
999
+ useDeleteAgentShare,
995
1000
  useRotateShareLink,
996
1001
  ShareAgentDialog,
997
- useShareAgent,
998
- useCreateExternalShareLink,
1002
+ AgentShareList,
999
1003
  useShareToolReadiness,
1000
1004
  validateOrigin,
1001
1005
  MAX_ALLOWED_ORIGINS,
@@ -1004,16 +1008,16 @@ export type {
1004
1008
  UseSharedAgentProfileOptions,
1005
1009
  UseSharedAgentProfileReturn,
1006
1010
  SharedAgentChatProps,
1011
+ AgentShareCreateIdentity,
1007
1012
  AgentShareDraft,
1008
1013
  SharingAudience,
1009
- UseAgentShareReturn,
1014
+ UseAgentSharesReturn,
1015
+ UseCanCreateAgentShareReturn,
1010
1016
  UseSaveAgentShareReturn,
1017
+ UseDeleteAgentShareReturn,
1011
1018
  UseRotateShareLinkReturn,
1012
1019
  ShareAgentDialogProps,
1013
- UseShareAgentArgs,
1014
- UseShareAgentReturn,
1015
- UseCreateExternalShareLinkArgs,
1016
- UseCreateExternalShareLinkReturn,
1020
+ AgentShareListProps,
1017
1021
  ShareToolReadiness,
1018
1022
  } from "./sharing/index.js";
1019
1023
 
@@ -1177,6 +1181,10 @@ export type { TabsProps, TabItem } from "./tabs/index.js";
1177
1181
  export { Switch } from "./switch/index.js";
1178
1182
  export type { SwitchProps } from "./switch/index.js";
1179
1183
 
1184
+ // Button — shared action primitive (variants for the console's action tiers)
1185
+ export { Button } from "./button/index.js";
1186
+ export type { ButtonProps, ButtonSize, ButtonVariant } from "./button/index.js";
1187
+
1180
1188
  // Resource Detail — headless hooks, action bar, and composed shell for resource detail pages
1181
1189
  export {
1182
1190
  useCopyResource,