@stigmer/react 0.0.79 → 0.0.80
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/agent/AgentDetailView.js +2 -2
- package/agent/AgentDetailView.js.map +1 -1
- package/agent/agentSetupReducer.d.ts +3 -3
- package/agent/agentSetupReducer.d.ts.map +1 -1
- package/agent/index.d.ts +1 -1
- package/agent/index.d.ts.map +1 -1
- package/agent/index.js +1 -1
- package/agent/index.js.map +1 -1
- package/agent/useAgentSetup.d.ts +4 -4
- package/agent/useAgentSetup.js +9 -9
- package/agent/useAgentSetup.js.map +1 -1
- package/environment/EnvVarForm.d.ts +9 -3
- package/environment/EnvVarForm.d.ts.map +1 -1
- package/environment/EnvVarForm.js +1 -1
- package/environment/EnvVarForm.js.map +1 -1
- package/environment/EnvironmentListPanel.d.ts +19 -4
- package/environment/EnvironmentListPanel.d.ts.map +1 -1
- package/environment/EnvironmentListPanel.js +7 -3
- package/environment/EnvironmentListPanel.js.map +1 -1
- package/environment/{diffEnvSpec.d.ts → diffEnv.d.ts} +9 -8
- package/environment/diffEnv.d.ts.map +1 -0
- package/environment/{diffEnvSpec.js → diffEnv.js} +10 -9
- package/environment/diffEnv.js.map +1 -0
- package/environment/index.d.ts +1 -1
- package/environment/index.d.ts.map +1 -1
- package/environment/index.js +1 -1
- package/environment/index.js.map +1 -1
- package/execution/SessionVariablesInput.d.ts +1 -1
- package/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/library/parse-resource-yaml.d.ts +1 -1
- package/library/parse-resource-yaml.d.ts.map +1 -1
- package/library/parse-resource-yaml.js +26 -16
- package/library/parse-resource-yaml.js.map +1 -1
- package/library/serialize-resource-yaml.js +17 -21
- package/library/serialize-resource-yaml.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts +8 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +27 -6
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/McpServerPicker.d.ts +8 -1
- package/mcp-server/McpServerPicker.d.ts.map +1 -1
- package/mcp-server/McpServerPicker.js +2 -2
- package/mcp-server/McpServerPicker.js.map +1 -1
- package/mcp-server/index.d.ts +2 -0
- package/mcp-server/index.d.ts.map +1 -1
- package/mcp-server/index.js +1 -0
- package/mcp-server/index.js.map +1 -1
- package/mcp-server/mcpServerSetupReducer.d.ts +4 -4
- package/mcp-server/useMcpServerCredentials.d.ts +32 -17
- package/mcp-server/useMcpServerCredentials.d.ts.map +1 -1
- package/mcp-server/useMcpServerCredentials.js +30 -19
- package/mcp-server/useMcpServerCredentials.js.map +1 -1
- package/mcp-server/useMcpServerSetup.d.ts +5 -5
- package/mcp-server/useMcpServerSetup.d.ts.map +1 -1
- package/mcp-server/useMcpServerSetup.js +33 -13
- package/mcp-server/useMcpServerSetup.js.map +1 -1
- package/mcp-server/useOAuthGrantStatus.d.ts +41 -0
- package/mcp-server/useOAuthGrantStatus.d.ts.map +1 -0
- package/mcp-server/useOAuthGrantStatus.js +91 -0
- package/mcp-server/useOAuthGrantStatus.js.map +1 -0
- package/package.json +4 -4
- package/src/agent/AgentDetailView.tsx +5 -5
- package/src/agent/agentSetupReducer.ts +3 -3
- package/src/agent/index.ts +1 -1
- package/src/agent/useAgentSetup.ts +11 -11
- package/src/environment/EnvVarForm.tsx +9 -3
- package/src/environment/EnvironmentListPanel.tsx +27 -9
- package/src/environment/{diffEnvSpec.ts → diffEnv.ts} +10 -9
- package/src/environment/index.ts +1 -1
- package/src/execution/SessionVariablesInput.tsx +1 -1
- package/src/index.ts +4 -2
- package/src/library/parse-resource-yaml.ts +27 -18
- package/src/library/serialize-resource-yaml.ts +20 -27
- package/src/mcp-server/McpServerDetailView.tsx +39 -7
- package/src/mcp-server/McpServerPicker.tsx +9 -1
- package/src/mcp-server/index.ts +3 -0
- package/src/mcp-server/mcpServerSetupReducer.ts +4 -4
- package/src/mcp-server/useMcpServerCredentials.ts +65 -32
- package/src/mcp-server/useMcpServerSetup.ts +38 -15
- package/src/mcp-server/useOAuthGrantStatus.ts +125 -0
- package/environment/diffEnvSpec.d.ts.map +0 -1
- package/environment/diffEnvSpec.js.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useReducer, useRef } from "react";
|
|
3
|
+
import { create } from "@bufbuild/protobuf";
|
|
4
|
+
import { GetOAuthGrantStatusInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
3
5
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
4
6
|
import { useStigmer } from "../hooks";
|
|
5
7
|
import { usePersonalEnvironment } from "../environment/usePersonalEnvironment";
|
|
6
|
-
import {
|
|
8
|
+
import { diffEnv } from "../environment/diffEnv";
|
|
7
9
|
import { toError } from "../internal/toError";
|
|
8
10
|
import { mcpServerSetupReducer, INITIAL_MCP_SETUP_STATE, toServerKey, } from "./mcpServerSetupReducer";
|
|
9
11
|
export { toServerKey } from "./mcpServerSetupReducer";
|
|
@@ -32,8 +34,8 @@ function computeDefaultEnabledTools(mcpServer, discoveredTools) {
|
|
|
32
34
|
* MCP servers selected in the {@link McpServerPicker}.
|
|
33
35
|
*
|
|
34
36
|
* When a user toggles an MCP server ON, this hook fetches the server's
|
|
35
|
-
* full resource, checks its `
|
|
36
|
-
* (via {@link
|
|
37
|
+
* full resource, checks its `env` declarations against the personal
|
|
38
|
+
* environment (via {@link diffEnv}), and determines whether credentials are
|
|
37
39
|
* needed. It also extracts discovered tools and approval policies for
|
|
38
40
|
* the tool selector UI.
|
|
39
41
|
*
|
|
@@ -59,7 +61,7 @@ function computeDefaultEnabledTools(mcpServer, discoveredTools) {
|
|
|
59
61
|
* @param org - Organization slug. Pass `null` to disable.
|
|
60
62
|
* @param poolKeys - Optional set of env-var keys already available
|
|
61
63
|
* from the session env pool (manual secrets, one-time env vars from
|
|
62
|
-
* other components). When provided, servers whose `
|
|
64
|
+
* other components). When provided, servers whose `env` keys
|
|
63
65
|
* are fully covered by `poolKeys` + personal env auto-resolve to
|
|
64
66
|
* `ready` without prompting. Reactive — when `poolKeys` changes,
|
|
65
67
|
* `needsSetup` entries are re-evaluated.
|
|
@@ -108,8 +110,8 @@ export function useMcpServerSetup(org, poolKeys) {
|
|
|
108
110
|
const mcpServer = await stigmer.mcpServer.getByReference(ref);
|
|
109
111
|
const discoveredTools = mcpServer.status?.discoveredCapabilities?.tools ?? [];
|
|
110
112
|
const toolApprovals = mcpServer.spec?.pinnedToolApprovals ?? [];
|
|
111
|
-
const
|
|
112
|
-
if (!
|
|
113
|
+
const envDeclarations = mcpServer.spec?.env;
|
|
114
|
+
if (!envDeclarations || Object.keys(envDeclarations).length === 0) {
|
|
113
115
|
dispatch({
|
|
114
116
|
type: "RESOLVE_READY",
|
|
115
117
|
key,
|
|
@@ -121,8 +123,25 @@ export function useMcpServerSetup(org, poolKeys) {
|
|
|
121
123
|
return;
|
|
122
124
|
}
|
|
123
125
|
const existingKeys = new Set(Object.keys(personalEnv.environment?.spec?.data ?? {}));
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
+
const auth = mcpServer.spec?.auth;
|
|
127
|
+
if (auth?.targetEnvVar && mcpServer.metadata?.id) {
|
|
128
|
+
try {
|
|
129
|
+
const grantStatus = await stigmer.mcpServer.getOAuthGrantStatus(create(GetOAuthGrantStatusInputSchema, {
|
|
130
|
+
resourceId: mcpServer.metadata.id,
|
|
131
|
+
org,
|
|
132
|
+
}));
|
|
133
|
+
if (grantStatus.connected) {
|
|
134
|
+
existingKeys.add(auth.targetEnvVar);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Non-fatal: if grant status lookup fails, the OAuth var stays
|
|
139
|
+
// in missingVariables and the UI shows the sign-in button.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const allMissing = diffEnv(envDeclarations, existingKeys, poolKeys);
|
|
143
|
+
const requiredMissing = allMissing.filter((v) => !v.optional);
|
|
144
|
+
if (requiredMissing.length === 0) {
|
|
126
145
|
dispatch({
|
|
127
146
|
type: "RESOLVE_READY",
|
|
128
147
|
key,
|
|
@@ -137,7 +156,7 @@ export function useMcpServerSetup(org, poolKeys) {
|
|
|
137
156
|
type: "RESOLVE_NEEDS_SETUP",
|
|
138
157
|
key,
|
|
139
158
|
mcpServer,
|
|
140
|
-
missingVariables,
|
|
159
|
+
missingVariables: requiredMissing,
|
|
141
160
|
discoveredTools,
|
|
142
161
|
toolApprovals,
|
|
143
162
|
});
|
|
@@ -215,12 +234,13 @@ export function useMcpServerSetup(org, poolKeys) {
|
|
|
215
234
|
for (const [key, entry] of Object.entries(entriesRef.current)) {
|
|
216
235
|
if (entry.status !== "needsSetup")
|
|
217
236
|
continue;
|
|
218
|
-
const
|
|
219
|
-
if (!
|
|
237
|
+
const envDeclarations = entry.mcpServer.spec?.env;
|
|
238
|
+
if (!envDeclarations)
|
|
220
239
|
continue;
|
|
221
|
-
const
|
|
240
|
+
const allMissing = diffEnv(envDeclarations, personalKeys, poolKeys);
|
|
241
|
+
const requiredMissing = allMissing.filter((v) => !v.optional);
|
|
222
242
|
const enabledTools = computeDefaultEnabledTools(entry.mcpServer, entry.discoveredTools);
|
|
223
|
-
dispatch({ type: "POOL_RESOLVE", key, missingVariables, enabledTools });
|
|
243
|
+
dispatch({ type: "POOL_RESOLVE", key, missingVariables: requiredMissing, enabledTools });
|
|
224
244
|
}
|
|
225
245
|
}, [poolKeys, personalEnv.environment]);
|
|
226
246
|
// -------------------------------------------------------------------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMcpServerSetup.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerSetup.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useMcpServerSetup.js","sourceRoot":"","sources":["../../src/mcp-server/useMcpServerSetup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Return value of {@link useOAuthGrantStatus}. */
|
|
2
|
+
export interface UseOAuthGrantStatusReturn {
|
|
3
|
+
/** Whether the user has an active OAuth grant for this resource + org. */
|
|
4
|
+
readonly connected: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* When the access token expires (Unix timestamp seconds).
|
|
7
|
+
* `BigInt(0)` when no grant exists or the token does not expire.
|
|
8
|
+
*/
|
|
9
|
+
readonly accessTokenExpiresAt: bigint;
|
|
10
|
+
/** The env var name managed by OAuth, or empty string when no grant exists. */
|
|
11
|
+
readonly targetEnvVar: string;
|
|
12
|
+
/** Auth method used (`"mcp_oauth"` or `"vendor_oauth"`), or empty string. */
|
|
13
|
+
readonly authMethod: string;
|
|
14
|
+
/** `true` while the grant status is being fetched. */
|
|
15
|
+
readonly isLoading: boolean;
|
|
16
|
+
/** Error from the last failed request, or `null` when healthy. */
|
|
17
|
+
readonly error: Error | null;
|
|
18
|
+
/** Discard cached data and re-fetch the grant status. */
|
|
19
|
+
readonly refetch: () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Data hook that fetches the OAuth grant status for a single MCP server.
|
|
23
|
+
*
|
|
24
|
+
* Wraps `stigmer.mcpServer.getOAuthGrantStatus()` with loading, error,
|
|
25
|
+
* and idle state management. When `resourceId` or `org` changes, the
|
|
26
|
+
* previous in-flight request is discarded and a fresh fetch begins.
|
|
27
|
+
*
|
|
28
|
+
* Pass `null` for either parameter to skip fetching (stable no-op).
|
|
29
|
+
* This is useful when the MCP server resource has not loaded yet.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const grantStatus = useOAuthGrantStatus(mcpServer?.metadata?.id ?? null, org);
|
|
34
|
+
*
|
|
35
|
+
* if (grantStatus.isLoading) return <Spinner />;
|
|
36
|
+
* if (grantStatus.connected) return <span>Connected via OAuth</span>;
|
|
37
|
+
* return <button onClick={startOAuth}>Sign in</button>;
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function useOAuthGrantStatus(resourceId: string | null, org: string | null): UseOAuthGrantStatusReturn;
|
|
41
|
+
//# sourceMappingURL=useOAuthGrantStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOAuthGrantStatus.d.ts","sourceRoot":"","sources":["../../src/mcp-server/useOAuthGrantStatus.ts"],"names":[],"mappings":"AAQA,mDAAmD;AACnD,MAAM,WAAW,yBAAyB;IACxC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAcD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,GAAG,EAAE,MAAM,GAAG,IAAI,GACjB,yBAAyB,CA6D3B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { create } from "@bufbuild/protobuf";
|
|
4
|
+
import { GetOAuthGrantStatusInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
5
|
+
import { useStigmer } from "../hooks";
|
|
6
|
+
import { toError } from "../internal/toError";
|
|
7
|
+
const BIGINT_ZERO = BigInt(0);
|
|
8
|
+
const IDLE = {
|
|
9
|
+
connected: false,
|
|
10
|
+
accessTokenExpiresAt: BIGINT_ZERO,
|
|
11
|
+
targetEnvVar: "",
|
|
12
|
+
authMethod: "",
|
|
13
|
+
isLoading: false,
|
|
14
|
+
error: null,
|
|
15
|
+
refetch: () => { },
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Data hook that fetches the OAuth grant status for a single MCP server.
|
|
19
|
+
*
|
|
20
|
+
* Wraps `stigmer.mcpServer.getOAuthGrantStatus()` with loading, error,
|
|
21
|
+
* and idle state management. When `resourceId` or `org` changes, the
|
|
22
|
+
* previous in-flight request is discarded and a fresh fetch begins.
|
|
23
|
+
*
|
|
24
|
+
* Pass `null` for either parameter to skip fetching (stable no-op).
|
|
25
|
+
* This is useful when the MCP server resource has not loaded yet.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* const grantStatus = useOAuthGrantStatus(mcpServer?.metadata?.id ?? null, org);
|
|
30
|
+
*
|
|
31
|
+
* if (grantStatus.isLoading) return <Spinner />;
|
|
32
|
+
* if (grantStatus.connected) return <span>Connected via OAuth</span>;
|
|
33
|
+
* return <button onClick={startOAuth}>Sign in</button>;
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function useOAuthGrantStatus(resourceId, org) {
|
|
37
|
+
const stigmer = useStigmer();
|
|
38
|
+
const [connected, setConnected] = useState(false);
|
|
39
|
+
const [accessTokenExpiresAt, setAccessTokenExpiresAt] = useState(BIGINT_ZERO);
|
|
40
|
+
const [targetEnvVar, setTargetEnvVar] = useState("");
|
|
41
|
+
const [authMethod, setAuthMethod] = useState("");
|
|
42
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
43
|
+
const [error, setError] = useState(null);
|
|
44
|
+
const [fetchKey, setFetchKey] = useState(0);
|
|
45
|
+
const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!resourceId || !org) {
|
|
48
|
+
setConnected(false);
|
|
49
|
+
setAccessTokenExpiresAt(BIGINT_ZERO);
|
|
50
|
+
setTargetEnvVar("");
|
|
51
|
+
setAuthMethod("");
|
|
52
|
+
setIsLoading(false);
|
|
53
|
+
setError(null);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const cancelled = { current: false };
|
|
57
|
+
setIsLoading(true);
|
|
58
|
+
setError(null);
|
|
59
|
+
stigmer.mcpServer
|
|
60
|
+
.getOAuthGrantStatus(create(GetOAuthGrantStatusInputSchema, { resourceId, org }))
|
|
61
|
+
.then((result) => {
|
|
62
|
+
if (cancelled.current)
|
|
63
|
+
return;
|
|
64
|
+
setConnected(result.connected);
|
|
65
|
+
setAccessTokenExpiresAt(result.accessTokenExpiresAt);
|
|
66
|
+
setTargetEnvVar(result.targetEnvVar);
|
|
67
|
+
setAuthMethod(result.authMethod);
|
|
68
|
+
setIsLoading(false);
|
|
69
|
+
}, (err) => {
|
|
70
|
+
if (cancelled.current)
|
|
71
|
+
return;
|
|
72
|
+
setError(toError(err));
|
|
73
|
+
setIsLoading(false);
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
cancelled.current = true;
|
|
77
|
+
};
|
|
78
|
+
}, [resourceId, org, stigmer, fetchKey]);
|
|
79
|
+
if (!resourceId || !org)
|
|
80
|
+
return { ...IDLE, refetch };
|
|
81
|
+
return {
|
|
82
|
+
connected,
|
|
83
|
+
accessTokenExpiresAt,
|
|
84
|
+
targetEnvVar,
|
|
85
|
+
authMethod,
|
|
86
|
+
isLoading,
|
|
87
|
+
error,
|
|
88
|
+
refetch,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=useOAuthGrantStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOAuthGrantStatus.js","sourceRoot":"","sources":["../../src/mcp-server/useOAuthGrantStatus.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,8BAA8B,EAAE,MAAM,uDAAuD,CAAC;AACvG,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAuB9C,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAE9B,MAAM,IAAI,GAA8B;IACtC,SAAS,EAAE,KAAK;IAChB,oBAAoB,EAAE,WAAW;IACjC,YAAY,EAAE,EAAE;IAChB,UAAU,EAAE,EAAE;IACd,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAyB,EACzB,GAAkB;IAElB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC9E,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,uBAAuB,CAAC,WAAW,CAAC,CAAC;YACrC,eAAe,CAAC,EAAE,CAAC,CAAC;YACpB,aAAa,CAAC,EAAE,CAAC,CAAC;YAClB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACrC,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,OAAO,CAAC,SAAS;aACd,mBAAmB,CAAC,MAAM,CAAC,8BAA8B,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;aAChF,IAAI,CACH,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,SAAS,CAAC,OAAO;gBAAE,OAAO;YAC9B,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,uBAAuB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACrD,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACrC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACjC,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACN,IAAI,SAAS,CAAC,OAAO;gBAAE,OAAO;YAC9B,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YACvB,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CACF,CAAC;QAEJ,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC;IAErD,OAAO;QACL,SAAS;QACT,oBAAoB;QACpB,YAAY;QACZ,UAAU;QACV,SAAS;QACT,KAAK;QACL,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.80",
|
|
4
4
|
"description": "React provider and client hook for the Stigmer platform SDK",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@stigmer/theme": "0.0.
|
|
38
|
+
"@stigmer/theme": "0.0.80",
|
|
39
39
|
"react-markdown": "^10.1.0",
|
|
40
40
|
"remark-gfm": "^4.0.1",
|
|
41
41
|
"yaml": "^2.8.2"
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@base-ui/react": "^1.0.0",
|
|
45
45
|
"@bufbuild/protobuf": "^2.0.0",
|
|
46
|
-
"@stigmer/protos": "0.0.
|
|
47
|
-
"@stigmer/sdk": "0.0.
|
|
46
|
+
"@stigmer/protos": "0.0.80",
|
|
47
|
+
"@stigmer/sdk": "0.0.80",
|
|
48
48
|
"react": "^19.0.0",
|
|
49
49
|
"react-dom": "^19.0.0"
|
|
50
50
|
}
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
SubAgent,
|
|
10
10
|
} from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
|
|
11
11
|
import type { ApiResourceReference } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
|
|
12
|
-
import type {
|
|
12
|
+
import type { EnvVarDeclaration } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
|
|
13
13
|
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
14
14
|
import { useAgent } from "./useAgent";
|
|
15
15
|
import { ErrorMessage } from "../error/ErrorMessage";
|
|
@@ -155,8 +155,8 @@ export function AgentDetailView({
|
|
|
155
155
|
<SubAgentsSection subAgents={spec.subAgents} />
|
|
156
156
|
)}
|
|
157
157
|
|
|
158
|
-
{spec?.
|
|
159
|
-
<
|
|
158
|
+
{spec?.env && Object.keys(spec.env).length > 0 && (
|
|
159
|
+
<EnvSection data={spec.env} />
|
|
160
160
|
)}
|
|
161
161
|
</div>
|
|
162
162
|
);
|
|
@@ -534,10 +534,10 @@ function SubAgentDetails({
|
|
|
534
534
|
);
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
-
function
|
|
537
|
+
function EnvSection({
|
|
538
538
|
data,
|
|
539
539
|
}: {
|
|
540
|
-
readonly data: { [key: string]:
|
|
540
|
+
readonly data: { [key: string]: EnvVarDeclaration };
|
|
541
541
|
}) {
|
|
542
542
|
const entries = Object.entries(data).sort(([a], [b]) =>
|
|
543
543
|
a.localeCompare(b),
|
|
@@ -14,8 +14,8 @@ import type { AgentEnvFormVariable } from "./AgentEnvForm";
|
|
|
14
14
|
* existed). Use `instanceId` with `createSession`.
|
|
15
15
|
* - `"oneTime"` — Secrets were collected but **not** persisted. Pass
|
|
16
16
|
* `runtimeEnv` to `createExecution` for this run only.
|
|
17
|
-
* - `"direct"` — The agent has no `
|
|
18
|
-
* Create the session with `agentRef` directly.
|
|
17
|
+
* - `"direct"` — The agent has no `env` declarations and needs no
|
|
18
|
+
* secrets. Create the session with `agentRef` directly.
|
|
19
19
|
*/
|
|
20
20
|
export type AgentResolution =
|
|
21
21
|
| {
|
|
@@ -31,7 +31,7 @@ export type AgentResolution =
|
|
|
31
31
|
readonly runtimeEnv: Record<string, EnvVarInput>;
|
|
32
32
|
}
|
|
33
33
|
| {
|
|
34
|
-
/** The agent has no `
|
|
34
|
+
/** The agent has no `env` declarations and needs no secrets. */
|
|
35
35
|
readonly mode: "direct";
|
|
36
36
|
};
|
|
37
37
|
|
package/src/agent/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { useStigmer } from "../hooks";
|
|
|
10
10
|
import { toError } from "../internal/toError";
|
|
11
11
|
import { usePersonalEnvironment } from "../environment/usePersonalEnvironment";
|
|
12
12
|
import { buildPersonalInstanceInput } from "../agent-instance/buildPersonalInstanceInput";
|
|
13
|
-
import {
|
|
13
|
+
import { diffEnv } from "../environment/diffEnv";
|
|
14
14
|
import {
|
|
15
15
|
agentSetupReducer,
|
|
16
16
|
INITIAL_STATE,
|
|
@@ -106,8 +106,8 @@ export interface UseAgentSetupReturn {
|
|
|
106
106
|
/**
|
|
107
107
|
* Evaluate whether an agent is ready to use or needs env var collection.
|
|
108
108
|
*
|
|
109
|
-
* Fetches the full agent to read its `
|
|
110
|
-
* personal instance, and diffs
|
|
109
|
+
* Fetches the full agent to read its `env` declarations, checks for an
|
|
110
|
+
* existing personal instance, and diffs env keys against the personal
|
|
111
111
|
* environment. Returns `"ready"` when the agent can be used immediately,
|
|
112
112
|
* or `"needsEnvVars"` when the caller should present {@link AgentEnvForm}.
|
|
113
113
|
*/
|
|
@@ -143,7 +143,7 @@ export interface UseAgentSetupReturn {
|
|
|
143
143
|
*
|
|
144
144
|
* When a user picks an agent in the {@link AgentPicker}, this hook
|
|
145
145
|
* determines whether the agent requires credentials (via its
|
|
146
|
-
* `
|
|
146
|
+
* `env` declarations), checks what the user has already provided in their
|
|
147
147
|
* personal environment, and either reports the agent as ready or
|
|
148
148
|
* identifies the missing variables so the caller can render
|
|
149
149
|
* {@link AgentEnvForm}.
|
|
@@ -173,7 +173,7 @@ export interface UseAgentSetupReturn {
|
|
|
173
173
|
* @param org - Organization slug. Pass `null` to disable.
|
|
174
174
|
* @param poolKeys - Optional set of env-var keys already available
|
|
175
175
|
* from the session env pool (manual secrets, one-time env vars from
|
|
176
|
-
* other components). When provided, agents whose `
|
|
176
|
+
* other components). When provided, agents whose `env` keys
|
|
177
177
|
* are fully covered by `poolKeys` + personal env auto-resolve to
|
|
178
178
|
* `ready` without prompting. Reactive — when `poolKeys` changes,
|
|
179
179
|
* `needsEnvVars` is re-evaluated.
|
|
@@ -221,10 +221,10 @@ export function useAgentSetup(
|
|
|
221
221
|
try {
|
|
222
222
|
const agent = await stigmer.agent.getByReference(ref);
|
|
223
223
|
const agentName = agent.metadata?.name ?? ref.slug;
|
|
224
|
-
const
|
|
224
|
+
const envDeclarations = agent.spec?.env;
|
|
225
225
|
|
|
226
|
-
// No
|
|
227
|
-
if (!
|
|
226
|
+
// No env declarations — agent is immediately ready (direct mode).
|
|
227
|
+
if (!envDeclarations || Object.keys(envDeclarations).length === 0) {
|
|
228
228
|
const resolution: AgentResolution = { mode: "direct" };
|
|
229
229
|
dispatch({
|
|
230
230
|
type: "RESOLVE_READY",
|
|
@@ -235,7 +235,7 @@ export function useAgentSetup(
|
|
|
235
235
|
return { status: "ready", agentRef: ref, agentName, resolution };
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
// Agent has
|
|
238
|
+
// Agent has env declarations — check for existing personal instance.
|
|
239
239
|
const agentLabel = `${ref.org}/${ref.slug}`;
|
|
240
240
|
const instanceList = await stigmer.agentInstance.list(
|
|
241
241
|
create(ListAgentInstancesRequestSchema, {
|
|
@@ -265,8 +265,8 @@ export function useAgentSetup(
|
|
|
265
265
|
const existingKeys = new Set(
|
|
266
266
|
Object.keys(personalEnv.environment?.spec?.data ?? {}),
|
|
267
267
|
);
|
|
268
|
-
const personalOnlyMissing =
|
|
269
|
-
const missingVariables =
|
|
268
|
+
const personalOnlyMissing = diffEnv(envDeclarations, existingKeys);
|
|
269
|
+
const missingVariables = diffEnv(envDeclarations, existingKeys, poolKeys);
|
|
270
270
|
|
|
271
271
|
if (personalOnlyMissing.length === 0) {
|
|
272
272
|
// Personal env covers all keys — create personal instance.
|
|
@@ -9,7 +9,7 @@ import { ScrollFade } from "../internal/ScrollFade";
|
|
|
9
9
|
/**
|
|
10
10
|
* Describes a single environment variable the form should collect.
|
|
11
11
|
*
|
|
12
|
-
* Typically derived from a resource's `
|
|
12
|
+
* Typically derived from a resource's `env` entries (Agent,
|
|
13
13
|
* McpServer, or any resource that declares required environment
|
|
14
14
|
* variables). The caller is responsible for filtering out variables
|
|
15
15
|
* the user has already provided (i.e. only pass the *missing* ones).
|
|
@@ -19,8 +19,14 @@ export interface EnvVarFormVariable {
|
|
|
19
19
|
readonly key: string;
|
|
20
20
|
/** When true, the input renders as a password field with a visibility toggle. */
|
|
21
21
|
readonly isSecret: boolean;
|
|
22
|
-
/** Help text shown below the input. From the resource's
|
|
22
|
+
/** Help text shown below the input. From the resource's env declaration description. */
|
|
23
23
|
readonly description?: string;
|
|
24
|
+
/**
|
|
25
|
+
* When true, this variable is not required for the resource to function.
|
|
26
|
+
* Callers can use this to filter optional vars out of forms or to show
|
|
27
|
+
* them separately from required vars.
|
|
28
|
+
*/
|
|
29
|
+
readonly optional?: boolean;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
/** Options reported by the form alongside the collected values on submit. */
|
|
@@ -110,7 +116,7 @@ export interface EnvVarFormProps {
|
|
|
110
116
|
|
|
111
117
|
/**
|
|
112
118
|
* Compact form that collects environment variable values for any
|
|
113
|
-
* resource that declares
|
|
119
|
+
* resource that declares `env` variables (Agents, MCP servers, etc.).
|
|
114
120
|
*
|
|
115
121
|
* Renders one labeled input per variable. Secret variables use a
|
|
116
122
|
* password field with a visibility toggle. The form validates that
|
|
@@ -18,11 +18,26 @@ export interface EnvironmentListPanelProps {
|
|
|
18
18
|
/** Optional label filter — only environments matching ALL labels are shown. */
|
|
19
19
|
readonly labels?: Record<string, string>;
|
|
20
20
|
/**
|
|
21
|
-
* Exclude environments whose labels
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* Exclude environments whose labels match one or more label sets.
|
|
22
|
+
*
|
|
23
|
+
* A single record uses AND semantics — the environment must match
|
|
24
|
+
* **all** key-value pairs to be excluded. Pass an array of records
|
|
25
|
+
* for OR-of-AND semantics: the environment is excluded when **any**
|
|
26
|
+
* record fully matches.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Exclude personal envs only (single record — backward-compatible)
|
|
31
|
+
* excludeLabels={{ "stigmer.ai/personal": "true" }}
|
|
32
|
+
*
|
|
33
|
+
* // Exclude personal AND managed envs (array of records)
|
|
34
|
+
* excludeLabels={[
|
|
35
|
+
* { "stigmer.ai/personal": "true" },
|
|
36
|
+
* { "stigmer.ai/managed": "true" },
|
|
37
|
+
* ]}
|
|
38
|
+
* ```
|
|
24
39
|
*/
|
|
25
|
-
readonly excludeLabels?: Record<string, string
|
|
40
|
+
readonly excludeLabels?: Record<string, string> | Record<string, string>[];
|
|
26
41
|
/** Fired when a user selects (expands) an environment. */
|
|
27
42
|
readonly onEnvironmentSelect?: (env: Environment) => void;
|
|
28
43
|
/** When `true`, variable editors render in read-only mode. */
|
|
@@ -82,13 +97,16 @@ export function EnvironmentListPanel({
|
|
|
82
97
|
}
|
|
83
98
|
|
|
84
99
|
const filtered = useMemo(() => {
|
|
85
|
-
if (!excludeLabels
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
if (!excludeLabels) return environments;
|
|
101
|
+
const labelSets = Array.isArray(excludeLabels)
|
|
102
|
+
? excludeLabels
|
|
103
|
+
: [excludeLabels];
|
|
104
|
+
if (labelSets.length === 0) return environments;
|
|
105
|
+
|
|
88
106
|
return environments.filter((env) => {
|
|
89
107
|
const envLabels = env.metadata?.labels ?? {};
|
|
90
|
-
const shouldExclude =
|
|
91
|
-
([k, v]) => envLabels[k] === v,
|
|
108
|
+
const shouldExclude = labelSets.some((labelSet) =>
|
|
109
|
+
Object.entries(labelSet).every(([k, v]) => envLabels[k] === v),
|
|
92
110
|
);
|
|
93
111
|
return !shouldExclude;
|
|
94
112
|
});
|
|
@@ -4,38 +4,38 @@ import type { EnvVarFormVariable } from "./EnvVarForm";
|
|
|
4
4
|
* Computes the list of environment variables a resource requires that
|
|
5
5
|
* the user has not yet provided.
|
|
6
6
|
*
|
|
7
|
-
* Compares a resource's declared `
|
|
7
|
+
* Compares a resource's declared `env` keys against a set of
|
|
8
8
|
* keys already present in the user's personal environment **and** an
|
|
9
9
|
* optional session-level env pool (manual secrets, one-time env vars
|
|
10
10
|
* from other components). Variables whose keys are missing from both
|
|
11
11
|
* sources are returned as {@link EnvVarFormVariable} entries suitable
|
|
12
12
|
* for rendering in {@link EnvVarForm}.
|
|
13
13
|
*
|
|
14
|
-
* Works with any resource that declares
|
|
14
|
+
* Works with any resource that declares env var declarations — Agents,
|
|
15
15
|
* MCP servers, or future resource types.
|
|
16
16
|
*
|
|
17
17
|
* This is a pure function with no side effects — it can be unit-tested
|
|
18
18
|
* independently of hooks, providers, or API calls.
|
|
19
19
|
*
|
|
20
|
-
* @param
|
|
21
|
-
* Each entry declares a variable the resource needs, with `isSecret
|
|
22
|
-
* and an optional
|
|
20
|
+
* @param envDeclarations - The resource's `spec.env` record.
|
|
21
|
+
* Each entry declares a variable the resource needs, with `isSecret`,
|
|
22
|
+
* an optional `description`, and an `optional` flag.
|
|
23
23
|
* @param existingKeys - Keys already present in the user's personal
|
|
24
24
|
* environment (or any environment being checked against).
|
|
25
25
|
* @param poolKeys - Optional additional keys from the session env pool
|
|
26
26
|
* (manual secrets, one-time env vars from other agents/MCP servers).
|
|
27
27
|
* When provided, variables satisfied by the pool are also excluded
|
|
28
28
|
* from the "missing" list.
|
|
29
|
-
* @returns Variables from `
|
|
29
|
+
* @returns Variables from `envDeclarations` not found in either key set.
|
|
30
30
|
*/
|
|
31
|
-
export function
|
|
32
|
-
|
|
31
|
+
export function diffEnv(
|
|
32
|
+
envDeclarations: Record<string, { isSecret: boolean; description?: string; optional?: boolean }>,
|
|
33
33
|
existingKeys: Set<string>,
|
|
34
34
|
poolKeys?: Set<string>,
|
|
35
35
|
): EnvVarFormVariable[] {
|
|
36
36
|
const missing: EnvVarFormVariable[] = [];
|
|
37
37
|
|
|
38
|
-
for (const [key, value] of Object.entries(
|
|
38
|
+
for (const [key, value] of Object.entries(envDeclarations)) {
|
|
39
39
|
if (existingKeys.has(key)) continue;
|
|
40
40
|
if (poolKeys?.has(key)) continue;
|
|
41
41
|
|
|
@@ -43,6 +43,7 @@ export function diffEnvSpec(
|
|
|
43
43
|
key,
|
|
44
44
|
isSecret: value.isSecret,
|
|
45
45
|
...(value.description && { description: value.description }),
|
|
46
|
+
...(value.optional && { optional: true }),
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
|
package/src/environment/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ export type {
|
|
|
35
35
|
EnvVarFormVariable,
|
|
36
36
|
EnvVarFormSubmitOptions,
|
|
37
37
|
} from "./EnvVarForm";
|
|
38
|
-
export {
|
|
38
|
+
export { diffEnv } from "./diffEnv";
|
|
39
39
|
export { useSessionEnvPool } from "./useSessionEnvPool";
|
|
40
40
|
export type {
|
|
41
41
|
SessionEnvPoolInput,
|
|
@@ -22,7 +22,7 @@ export interface SessionVariablesInputProps {
|
|
|
22
22
|
* between the variable and the agent/MCP server that needs it.
|
|
23
23
|
*
|
|
24
24
|
* Built by `SessionComposer` from the selected agent's and MCP
|
|
25
|
-
* servers' `
|
|
25
|
+
* servers' `env` declarations.
|
|
26
26
|
*
|
|
27
27
|
* @example
|
|
28
28
|
* ```ts
|
package/src/index.ts
CHANGED
|
@@ -221,6 +221,7 @@ export {
|
|
|
221
221
|
useMcpServerConnect,
|
|
222
222
|
useMcpServerOAuthConnect,
|
|
223
223
|
useMcpServerCredentials,
|
|
224
|
+
useOAuthGrantStatus,
|
|
224
225
|
OAuthCallbackHandler,
|
|
225
226
|
McpServerPicker,
|
|
226
227
|
McpServerConfigPanel,
|
|
@@ -255,6 +256,7 @@ export type {
|
|
|
255
256
|
OAuthCallbackHandlerProps,
|
|
256
257
|
OAuthCallbackParams,
|
|
257
258
|
UseMcpServerCredentialsReturn,
|
|
259
|
+
UseOAuthGrantStatusReturn,
|
|
258
260
|
McpServerAuthMode,
|
|
259
261
|
} from "./mcp-server";
|
|
260
262
|
|
|
@@ -298,7 +300,7 @@ export type {
|
|
|
298
300
|
GitHubRepoPickerProps,
|
|
299
301
|
} from "./github";
|
|
300
302
|
|
|
301
|
-
// Agent — data hook, count hook, list hook, search hook, picker, detail view, env form, setup orchestration,
|
|
303
|
+
// Agent — data hook, count hook, list hook, search hook, picker, detail view, env form, setup orchestration, env diffing, and default agent
|
|
302
304
|
export {
|
|
303
305
|
useAgent,
|
|
304
306
|
useAgentCount,
|
|
@@ -307,7 +309,7 @@ export {
|
|
|
307
309
|
AgentPicker,
|
|
308
310
|
AgentDetailView,
|
|
309
311
|
AgentEnvForm,
|
|
310
|
-
|
|
312
|
+
diffEnv,
|
|
311
313
|
useAgentSetup,
|
|
312
314
|
useDefaultAgent,
|
|
313
315
|
} from "./agent";
|