@stigmer/react 0.0.101 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/AgentPicker.js +1 -1
- package/agent/AgentPicker.js.map +1 -1
- package/agent/__tests__/useDefaultAgent.test.d.ts +2 -0
- package/agent/__tests__/useDefaultAgent.test.d.ts.map +1 -0
- package/agent/__tests__/useDefaultAgent.test.js +252 -0
- package/agent/__tests__/useDefaultAgent.test.js.map +1 -0
- package/agent/useAgent.d.ts +2 -0
- package/agent/useAgent.d.ts.map +1 -1
- package/agent/useAgent.js +14 -37
- package/agent/useAgent.js.map +1 -1
- package/agent/useAgentCount.d.ts +1 -1
- package/agent/useAgentCount.d.ts.map +1 -1
- package/agent/useAgentList.d.ts +2 -2
- package/agent/useAgentList.d.ts.map +1 -1
- package/agent/useDefaultAgent.d.ts +6 -2
- package/agent/useDefaultAgent.d.ts.map +1 -1
- package/agent/useDefaultAgent.js +51 -31
- package/agent/useDefaultAgent.js.map +1 -1
- package/agent-instance/useAgentInstance.d.ts +2 -0
- package/agent-instance/useAgentInstance.d.ts.map +1 -1
- package/agent-instance/useAgentInstance.js +6 -33
- package/agent-instance/useAgentInstance.js.map +1 -1
- package/agent-instance/useAgentInstanceList.d.ts +2 -0
- package/agent-instance/useAgentInstanceList.d.ts.map +1 -1
- package/agent-instance/useAgentInstanceList.js +22 -40
- package/agent-instance/useAgentInstanceList.js.map +1 -1
- package/api-key/useApiKeyList.d.ts +2 -0
- package/api-key/useApiKeyList.d.ts.map +1 -1
- package/api-key/useApiKeyList.js +3 -27
- package/api-key/useApiKeyList.js.map +1 -1
- package/composer/ComposerToolbar.d.ts +1 -5
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +3 -4
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/ContextChip.d.ts +1 -1
- package/composer/ContextChip.d.ts.map +1 -1
- package/composer/ContextChip.js +1 -0
- package/composer/ContextChip.js.map +1 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +77 -4
- package/composer/SessionComposer.js.map +1 -1
- package/composer/icons.d.ts +1 -0
- package/composer/icons.d.ts.map +1 -1
- package/composer/icons.js +3 -0
- package/composer/icons.js.map +1 -1
- package/environment/useEnvironment.d.ts +2 -0
- package/environment/useEnvironment.d.ts.map +1 -1
- package/environment/useEnvironment.js +6 -33
- package/environment/useEnvironment.js.map +1 -1
- package/environment/useEnvironmentList.d.ts +2 -0
- package/environment/useEnvironmentList.d.ts.map +1 -1
- package/environment/useEnvironmentList.js +23 -53
- package/environment/useEnvironmentList.js.map +1 -1
- package/execution/ArtifactPreviewModal.js +1 -1
- package/execution/ArtifactPreviewModal.js.map +1 -1
- package/execution/useArtifactContent.d.ts +4 -2
- package/execution/useArtifactContent.d.ts.map +1 -1
- package/execution/useArtifactContent.js +23 -45
- package/execution/useArtifactContent.js.map +1 -1
- package/iam-policy/usePrincipalsCount.d.ts +2 -0
- package/iam-policy/usePrincipalsCount.d.ts.map +1 -1
- package/iam-policy/usePrincipalsCount.js +7 -46
- package/iam-policy/usePrincipalsCount.js.map +1 -1
- package/iam-policy/useResourceAccess.d.ts +2 -0
- package/iam-policy/useResourceAccess.d.ts.map +1 -1
- package/iam-policy/useResourceAccess.js +12 -47
- package/iam-policy/useResourceAccess.js.map +1 -1
- package/identity-provider/useIdentityProvider.d.ts +2 -0
- package/identity-provider/useIdentityProvider.d.ts.map +1 -1
- package/identity-provider/useIdentityProvider.js +3 -33
- package/identity-provider/useIdentityProvider.js.map +1 -1
- package/identity-provider/useIdentityProviderList.d.ts +2 -0
- package/identity-provider/useIdentityProviderList.d.ts.map +1 -1
- package/identity-provider/useIdentityProviderList.js +7 -33
- package/identity-provider/useIdentityProviderList.js.map +1 -1
- package/index.d.ts +2 -2
- package/index.d.ts.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/internal/__tests__/useFetch.test.d.ts +2 -0
- package/internal/__tests__/useFetch.test.d.ts.map +1 -0
- package/internal/__tests__/useFetch.test.js +95 -0
- package/internal/__tests__/useFetch.test.js.map +1 -0
- package/internal/useFetch.d.ts +51 -0
- package/internal/useFetch.d.ts.map +1 -0
- package/internal/useFetch.js +75 -0
- package/internal/useFetch.js.map +1 -0
- package/invitation/useInvitationPreview.d.ts +2 -0
- package/invitation/useInvitationPreview.d.ts.map +1 -1
- package/invitation/useInvitationPreview.js +5 -35
- package/invitation/useInvitationPreview.js.map +1 -1
- package/invitation/useOrgInvitations.d.ts +2 -0
- package/invitation/useOrgInvitations.d.ts.map +1 -1
- package/invitation/useOrgInvitations.js +6 -34
- package/invitation/useOrgInvitations.js.map +1 -1
- package/library/ResourceListView.d.ts +2 -2
- package/library/ResourceListView.d.ts.map +1 -1
- package/library/ResourceListView.js +1 -1
- package/library/ResourceListView.js.map +1 -1
- package/library/useDetectSkillPackage.d.ts +1 -1
- package/library/useDetectSkillPackage.d.ts.map +1 -1
- package/mcp-server/McpServerPicker.js +1 -1
- package/mcp-server/McpServerPicker.js.map +1 -1
- package/mcp-server/useMcpServer.d.ts +2 -0
- package/mcp-server/useMcpServer.d.ts.map +1 -1
- package/mcp-server/useMcpServer.js +13 -37
- package/mcp-server/useMcpServer.js.map +1 -1
- package/mcp-server/useMcpServerCount.d.ts +1 -1
- package/mcp-server/useMcpServerCount.d.ts.map +1 -1
- package/mcp-server/useMcpServerList.d.ts +2 -2
- package/mcp-server/useMcpServerList.d.ts.map +1 -1
- package/mcp-server/useOAuthGrantStatus.d.ts +2 -0
- package/mcp-server/useOAuthGrantStatus.d.ts.map +1 -1
- package/mcp-server/useOAuthGrantStatus.js +14 -61
- package/mcp-server/useOAuthGrantStatus.js.map +1 -1
- package/mcp-server/useOrgOAuthApp.d.ts +2 -0
- package/mcp-server/useOrgOAuthApp.d.ts.map +1 -1
- package/mcp-server/useOrgOAuthApp.js +19 -43
- package/mcp-server/useOrgOAuthApp.js.map +1 -1
- package/oauth-app/useOAuthAppList.d.ts +2 -0
- package/oauth-app/useOAuthAppList.d.ts.map +1 -1
- package/oauth-app/useOAuthAppList.js +6 -34
- package/oauth-app/useOAuthAppList.js.map +1 -1
- package/organization/useOrganization.d.ts +2 -0
- package/organization/useOrganization.d.ts.map +1 -1
- package/organization/useOrganization.js +3 -33
- package/organization/useOrganization.js.map +1 -1
- package/package.json +4 -4
- package/platform-client/usePlatformClient.d.ts +2 -0
- package/platform-client/usePlatformClient.d.ts.map +1 -1
- package/platform-client/usePlatformClient.js +3 -33
- package/platform-client/usePlatformClient.js.map +1 -1
- package/platform-client/usePlatformClientList.d.ts +2 -0
- package/platform-client/usePlatformClientList.d.ts.map +1 -1
- package/platform-client/usePlatformClientList.js +6 -34
- package/platform-client/usePlatformClientList.js.map +1 -1
- package/runner/RunnerListPanel.d.ts.map +1 -1
- package/runner/RunnerListPanel.js +21 -5
- package/runner/RunnerListPanel.js.map +1 -1
- package/runner/__tests__/phase.test.d.ts +2 -0
- package/runner/__tests__/phase.test.d.ts.map +1 -0
- package/runner/__tests__/phase.test.js +33 -0
- package/runner/__tests__/phase.test.js.map +1 -0
- package/runner/__tests__/useRunnerList.test.d.ts +2 -0
- package/runner/__tests__/useRunnerList.test.d.ts.map +1 -0
- package/runner/__tests__/useRunnerList.test.js +68 -0
- package/runner/__tests__/useRunnerList.test.js.map +1 -0
- package/runner/index.d.ts +3 -1
- package/runner/index.d.ts.map +1 -1
- package/runner/index.js +2 -1
- package/runner/index.js.map +1 -1
- package/runner/phase.d.ts +13 -0
- package/runner/phase.d.ts.map +1 -1
- package/runner/phase.js +15 -0
- package/runner/phase.js.map +1 -1
- package/runner/useRunnerCredential.d.ts +66 -0
- package/runner/useRunnerCredential.d.ts.map +1 -0
- package/runner/useRunnerCredential.js +50 -0
- package/runner/useRunnerCredential.js.map +1 -0
- package/runner/useRunnerList.d.ts +21 -0
- package/runner/useRunnerList.d.ts.map +1 -1
- package/runner/useRunnerList.js +9 -36
- package/runner/useRunnerList.js.map +1 -1
- package/search/useResourceCount.d.ts +2 -1
- package/search/useResourceCount.d.ts.map +1 -1
- package/search/useResourceCount.js +13 -37
- package/search/useResourceCount.js.map +1 -1
- package/search/useResourceList.d.ts +2 -1
- package/search/useResourceList.d.ts.map +1 -1
- package/search/useResourceList.js +26 -46
- package/search/useResourceList.js.map +1 -1
- package/search/useResourceSearch.d.ts +4 -2
- package/search/useResourceSearch.d.ts.map +1 -1
- package/search/useResourceSearch.js +7 -27
- package/search/useResourceSearch.js.map +1 -1
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +26 -1
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSession.d.ts +3 -1
- package/session/useSession.d.ts.map +1 -1
- package/session/useSession.js +3 -33
- package/session/useSession.js.map +1 -1
- package/session/useSessionExecutions.d.ts +3 -1
- package/session/useSessionExecutions.d.ts.map +1 -1
- package/session/useSessionExecutions.js +6 -34
- package/session/useSessionExecutions.js.map +1 -1
- package/session/useSessionList.d.ts +5 -3
- package/session/useSessionList.d.ts.map +1 -1
- package/session/useSessionList.js +9 -31
- package/session/useSessionList.js.map +1 -1
- package/skill/SkillPicker.js +1 -1
- package/skill/SkillPicker.js.map +1 -1
- package/skill/useSkill.d.ts +2 -0
- package/skill/useSkill.d.ts.map +1 -1
- package/skill/useSkill.js +13 -37
- package/skill/useSkill.js.map +1 -1
- package/skill/useSkillCount.d.ts +1 -1
- package/skill/useSkillCount.d.ts.map +1 -1
- package/skill/useSkillList.d.ts +2 -2
- package/skill/useSkillList.d.ts.map +1 -1
- package/src/agent/AgentPicker.tsx +1 -1
- package/src/agent/__tests__/useDefaultAgent.test.tsx +308 -0
- package/src/agent/useAgent.ts +19 -41
- package/src/agent/useAgentCount.ts +1 -1
- package/src/agent/useAgentList.ts +2 -2
- package/src/agent/useDefaultAgent.ts +67 -35
- package/src/agent-instance/useAgentInstance.ts +13 -37
- package/src/agent-instance/useAgentInstanceList.ts +31 -47
- package/src/api-key/useApiKeyList.ts +9 -32
- package/src/composer/ComposerToolbar.tsx +1 -22
- package/src/composer/ContextChip.tsx +2 -1
- package/src/composer/SessionComposer.tsx +206 -5
- package/src/composer/icons.tsx +27 -0
- package/src/environment/useEnvironment.ts +13 -37
- package/src/environment/useEnvironmentList.ts +31 -58
- package/src/execution/ArtifactPreviewModal.tsx +2 -2
- package/src/execution/useArtifactContent.ts +48 -65
- package/src/iam-policy/usePrincipalsCount.ts +17 -53
- package/src/iam-policy/useResourceAccess.ts +18 -55
- package/src/identity-provider/useIdentityProvider.ts +9 -39
- package/src/identity-provider/useIdentityProviderList.ts +14 -40
- package/src/index.ts +4 -0
- package/src/internal/__tests__/useFetch.test.ts +133 -0
- package/src/internal/useFetch.ts +121 -0
- package/src/invitation/useInvitationPreview.ts +14 -40
- package/src/invitation/useOrgInvitations.ts +15 -41
- package/src/library/ResourceListView.tsx +3 -3
- package/src/library/useDetectSkillPackage.ts +1 -1
- package/src/mcp-server/McpServerPicker.tsx +1 -1
- package/src/mcp-server/useMcpServer.ts +17 -42
- package/src/mcp-server/useMcpServerCount.ts +1 -1
- package/src/mcp-server/useMcpServerList.ts +2 -2
- package/src/mcp-server/useOAuthGrantStatus.ts +31 -69
- package/src/mcp-server/useOrgOAuthApp.ts +34 -51
- package/src/oauth-app/useOAuthAppList.ts +15 -41
- package/src/organization/useOrganization.ts +9 -38
- package/src/platform-client/usePlatformClient.ts +9 -39
- package/src/platform-client/usePlatformClientList.ts +14 -42
- package/src/runner/RunnerListPanel.tsx +49 -41
- package/src/runner/__tests__/phase.test.ts +35 -0
- package/src/runner/__tests__/useRunnerList.test.tsx +96 -0
- package/src/runner/index.ts +7 -0
- package/src/runner/phase.ts +16 -0
- package/src/runner/useRunnerCredential.ts +89 -0
- package/src/runner/useRunnerList.ts +36 -44
- package/src/search/useResourceCount.ts +20 -48
- package/src/search/useResourceList.ts +40 -57
- package/src/search/useResourceSearch.ts +22 -43
- package/src/session/useNewSessionFlow.ts +35 -1
- package/src/session/useSession.ts +10 -39
- package/src/session/useSessionExecutions.ts +20 -46
- package/src/session/useSessionList.ts +21 -42
- package/src/skill/SkillPicker.tsx +1 -1
- package/src/skill/useSkill.ts +17 -42
- package/src/skill/useSkillCount.ts +1 -1
- package/src/skill/useSkillList.ts +2 -2
- package/src/usage/useOrgUsageReport.ts +18 -46
- package/styles.css +1 -1
- package/usage/useOrgUsageReport.d.ts +2 -0
- package/usage/useOrgUsageReport.d.ts.map +1 -1
- package/usage/useOrgUsageReport.js +5 -35
- package/usage/useOrgUsageReport.js.map +1 -1
|
@@ -30,11 +30,19 @@ import {
|
|
|
30
30
|
SYSTEM_ENV_VAR_KEYS,
|
|
31
31
|
resolveSystemEnvVarValues,
|
|
32
32
|
} from "../environment/systemEnvVars";
|
|
33
|
+
import { RunnerPhase } from "@stigmer/protos/ai/stigmer/agentic/runner/v1/enum_pb";
|
|
34
|
+
import {
|
|
35
|
+
isActivePhase,
|
|
36
|
+
phaseLabel,
|
|
37
|
+
phaseDotColor,
|
|
38
|
+
PHASE_SORT_ORDER,
|
|
39
|
+
} from "../runner/phase";
|
|
33
40
|
import {
|
|
34
41
|
AgentIcon,
|
|
35
42
|
McpServerIcon,
|
|
36
43
|
SkillIcon,
|
|
37
44
|
SecretsIcon,
|
|
45
|
+
RunnerIcon,
|
|
38
46
|
AlertTriangleIcon,
|
|
39
47
|
ResolveSpinner,
|
|
40
48
|
} from "./icons";
|
|
@@ -927,6 +935,15 @@ export function SessionComposer({
|
|
|
927
935
|
}
|
|
928
936
|
}
|
|
929
937
|
|
|
938
|
+
if (showRunner && runnerId) {
|
|
939
|
+
items.push({
|
|
940
|
+
key: `runner:${runnerId}`,
|
|
941
|
+
label: selectedRunnerName ?? "Runner",
|
|
942
|
+
type: "runner",
|
|
943
|
+
onRemove: () => onRunnerIdChange?.(null),
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
|
|
930
947
|
if (sessionVariables) {
|
|
931
948
|
for (const entry of sessionVariables.entries) {
|
|
932
949
|
const k = entry.key.trim();
|
|
@@ -951,6 +968,10 @@ export function SessionComposer({
|
|
|
951
968
|
mcpSetup.entries,
|
|
952
969
|
mcpSetup.removeServer,
|
|
953
970
|
skillRefs,
|
|
971
|
+
showRunner,
|
|
972
|
+
runnerId,
|
|
973
|
+
selectedRunnerName,
|
|
974
|
+
onRunnerIdChange,
|
|
954
975
|
sessionVariables,
|
|
955
976
|
displayNames,
|
|
956
977
|
onSkillRefsChange,
|
|
@@ -1025,6 +1046,14 @@ export function SessionComposer({
|
|
|
1025
1046
|
count: skillCount,
|
|
1026
1047
|
});
|
|
1027
1048
|
}
|
|
1049
|
+
if (showRunner) {
|
|
1050
|
+
items.push({
|
|
1051
|
+
id: "runner",
|
|
1052
|
+
icon: <RunnerIcon />,
|
|
1053
|
+
label: "Runner",
|
|
1054
|
+
count: runnerId ? 1 : 0,
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1028
1057
|
if (showSessionVars) {
|
|
1029
1058
|
items.push({
|
|
1030
1059
|
id: "sessionVars",
|
|
@@ -1034,7 +1063,7 @@ export function SessionComposer({
|
|
|
1034
1063
|
});
|
|
1035
1064
|
}
|
|
1036
1065
|
return items;
|
|
1037
|
-
}, [showAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showSessionVars, sessionVarCount]);
|
|
1066
|
+
}, [showAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showRunner, runnerId, showSessionVars, sessionVarCount]);
|
|
1038
1067
|
|
|
1039
1068
|
const renderConfigPanel = useCallback(
|
|
1040
1069
|
(panelId: string): React.ReactNode => {
|
|
@@ -1119,6 +1148,16 @@ export function SessionComposer({
|
|
|
1119
1148
|
/>
|
|
1120
1149
|
);
|
|
1121
1150
|
|
|
1151
|
+
case "runner":
|
|
1152
|
+
return (
|
|
1153
|
+
<RunnerConfigPanel
|
|
1154
|
+
org={org!}
|
|
1155
|
+
value={runnerId ?? null}
|
|
1156
|
+
onChange={(id) => onRunnerIdChange?.(id)}
|
|
1157
|
+
disabled={isDisabled}
|
|
1158
|
+
/>
|
|
1159
|
+
);
|
|
1160
|
+
|
|
1122
1161
|
case "sessionVars":
|
|
1123
1162
|
return (
|
|
1124
1163
|
<SessionVariablesInput
|
|
@@ -1145,6 +1184,8 @@ export function SessionComposer({
|
|
|
1145
1184
|
mcpSetup,
|
|
1146
1185
|
skillRefs,
|
|
1147
1186
|
onSkillRefsChange,
|
|
1187
|
+
runnerId,
|
|
1188
|
+
onRunnerIdChange,
|
|
1148
1189
|
sessionVariables,
|
|
1149
1190
|
pool,
|
|
1150
1191
|
requiredByMap,
|
|
@@ -1321,10 +1362,6 @@ export function SessionComposer({
|
|
|
1321
1362
|
configActivePanel={configActivePanel}
|
|
1322
1363
|
onConfigActivePanelChange={handleConfigActivePanelChange}
|
|
1323
1364
|
renderConfigPanel={renderConfigPanel}
|
|
1324
|
-
showRunner={showRunner}
|
|
1325
|
-
runnerOrg={org ?? ""}
|
|
1326
|
-
runnerId={runnerId ?? null}
|
|
1327
|
-
onRunnerIdChange={onRunnerIdChange ?? (() => {})}
|
|
1328
1365
|
showModelSelector={showModelSelector}
|
|
1329
1366
|
modelId={modelId}
|
|
1330
1367
|
onModelChange={handleModelChange}
|
|
@@ -1361,3 +1398,167 @@ function mcpRefFromKey(key: string): ResourceRef {
|
|
|
1361
1398
|
kind: ApiResourceKind.mcp_server,
|
|
1362
1399
|
};
|
|
1363
1400
|
}
|
|
1401
|
+
|
|
1402
|
+
// ---------------------------------------------------------------------------
|
|
1403
|
+
// Runner config panel — inline list for the Configure menu
|
|
1404
|
+
// ---------------------------------------------------------------------------
|
|
1405
|
+
|
|
1406
|
+
function RunnerConfigPanel({
|
|
1407
|
+
org,
|
|
1408
|
+
value,
|
|
1409
|
+
onChange,
|
|
1410
|
+
disabled,
|
|
1411
|
+
}: {
|
|
1412
|
+
org: string;
|
|
1413
|
+
value: string | null;
|
|
1414
|
+
onChange: (runnerId: string | null) => void;
|
|
1415
|
+
disabled?: boolean;
|
|
1416
|
+
}) {
|
|
1417
|
+
const { runners, isLoading } = useRunnerList(org);
|
|
1418
|
+
|
|
1419
|
+
const { active, inactive } = useMemo(() => {
|
|
1420
|
+
type R = (typeof runners)[number];
|
|
1421
|
+
const act: R[] = [];
|
|
1422
|
+
const inact: R[] = [];
|
|
1423
|
+
for (const r of runners) {
|
|
1424
|
+
if (isActivePhase(r.status?.phase ?? RunnerPhase.UNSPECIFIED)) {
|
|
1425
|
+
act.push(r);
|
|
1426
|
+
} else {
|
|
1427
|
+
inact.push(r);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
const sorter = (a: R, b: R) => {
|
|
1431
|
+
const pa = a.status?.phase ?? RunnerPhase.UNSPECIFIED;
|
|
1432
|
+
const pb = b.status?.phase ?? RunnerPhase.UNSPECIFIED;
|
|
1433
|
+
const po = PHASE_SORT_ORDER[pa] - PHASE_SORT_ORDER[pb];
|
|
1434
|
+
if (po !== 0) return po;
|
|
1435
|
+
return (a.metadata?.name ?? "").localeCompare(b.metadata?.name ?? "");
|
|
1436
|
+
};
|
|
1437
|
+
act.sort(sorter);
|
|
1438
|
+
inact.sort(sorter);
|
|
1439
|
+
return { active: act, inactive: inact };
|
|
1440
|
+
}, [runners]);
|
|
1441
|
+
|
|
1442
|
+
const isAutoSelected = value === null;
|
|
1443
|
+
|
|
1444
|
+
return (
|
|
1445
|
+
<div className="w-72 space-y-1">
|
|
1446
|
+
{/* Auto option */}
|
|
1447
|
+
<button
|
|
1448
|
+
type="button"
|
|
1449
|
+
onClick={() => onChange(null)}
|
|
1450
|
+
disabled={disabled}
|
|
1451
|
+
className={cn(
|
|
1452
|
+
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs transition-colors",
|
|
1453
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
1454
|
+
isAutoSelected
|
|
1455
|
+
? "bg-accent font-medium text-foreground"
|
|
1456
|
+
: "text-foreground hover:bg-accent-hover",
|
|
1457
|
+
)}
|
|
1458
|
+
role="option"
|
|
1459
|
+
aria-selected={isAutoSelected}
|
|
1460
|
+
>
|
|
1461
|
+
<span className="inline-block h-1.5 w-1.5 shrink-0 rounded-full bg-primary" aria-hidden="true" />
|
|
1462
|
+
<span className="flex-1">Default</span>
|
|
1463
|
+
<span className="text-[0.6rem] text-muted-foreground">auto</span>
|
|
1464
|
+
</button>
|
|
1465
|
+
|
|
1466
|
+
{/* Available runners */}
|
|
1467
|
+
{active.length > 0 && (
|
|
1468
|
+
<>
|
|
1469
|
+
<div className="px-2 pt-1 text-[0.65rem] font-medium uppercase tracking-wider text-muted-foreground">
|
|
1470
|
+
Available
|
|
1471
|
+
</div>
|
|
1472
|
+
{active.map((r) => {
|
|
1473
|
+
const id = r.metadata!.id;
|
|
1474
|
+
const name = r.metadata?.name ?? "Unnamed";
|
|
1475
|
+
const phase = r.status?.phase ?? RunnerPhase.UNSPECIFIED;
|
|
1476
|
+
const hostname = r.status?.connectionInfo?.hostname;
|
|
1477
|
+
const isSelected = value === id;
|
|
1478
|
+
return (
|
|
1479
|
+
<button
|
|
1480
|
+
key={id}
|
|
1481
|
+
type="button"
|
|
1482
|
+
onClick={() => onChange(id)}
|
|
1483
|
+
disabled={disabled}
|
|
1484
|
+
className={cn(
|
|
1485
|
+
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs transition-colors",
|
|
1486
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
1487
|
+
isSelected
|
|
1488
|
+
? "bg-accent font-medium text-foreground"
|
|
1489
|
+
: "text-foreground hover:bg-accent-hover",
|
|
1490
|
+
)}
|
|
1491
|
+
role="option"
|
|
1492
|
+
aria-selected={isSelected}
|
|
1493
|
+
>
|
|
1494
|
+
<span
|
|
1495
|
+
className={`inline-block h-1.5 w-1.5 shrink-0 rounded-full ${phaseDotColor(phase)}`}
|
|
1496
|
+
aria-hidden="true"
|
|
1497
|
+
/>
|
|
1498
|
+
<div className="flex min-w-0 flex-1 flex-col">
|
|
1499
|
+
<span className="truncate">{name}</span>
|
|
1500
|
+
{hostname && (
|
|
1501
|
+
<span className="truncate text-[0.6rem] leading-tight text-muted-foreground">
|
|
1502
|
+
{hostname}
|
|
1503
|
+
</span>
|
|
1504
|
+
)}
|
|
1505
|
+
</div>
|
|
1506
|
+
<span className="shrink-0 text-[0.6rem] lowercase text-muted-foreground">
|
|
1507
|
+
{phaseLabel(phase)}
|
|
1508
|
+
</span>
|
|
1509
|
+
</button>
|
|
1510
|
+
);
|
|
1511
|
+
})}
|
|
1512
|
+
</>
|
|
1513
|
+
)}
|
|
1514
|
+
|
|
1515
|
+
{/* Offline runners */}
|
|
1516
|
+
{inactive.length > 0 && (
|
|
1517
|
+
<>
|
|
1518
|
+
<div className="px-2 pt-1 text-[0.65rem] font-medium uppercase tracking-wider text-muted-foreground">
|
|
1519
|
+
Offline
|
|
1520
|
+
</div>
|
|
1521
|
+
{inactive.map((r) => {
|
|
1522
|
+
const id = r.metadata!.id;
|
|
1523
|
+
const name = r.metadata?.name ?? "Unnamed";
|
|
1524
|
+
const phase = r.status?.phase ?? RunnerPhase.UNSPECIFIED;
|
|
1525
|
+
return (
|
|
1526
|
+
<div
|
|
1527
|
+
key={id}
|
|
1528
|
+
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-muted-foreground opacity-50"
|
|
1529
|
+
>
|
|
1530
|
+
<span
|
|
1531
|
+
className={`inline-block h-1.5 w-1.5 shrink-0 rounded-full ${phaseDotColor(phase)}`}
|
|
1532
|
+
aria-hidden="true"
|
|
1533
|
+
/>
|
|
1534
|
+
<span className="min-w-0 flex-1 truncate">{name}</span>
|
|
1535
|
+
<span className="shrink-0 text-[0.6rem] lowercase">
|
|
1536
|
+
{phaseLabel(phase)}
|
|
1537
|
+
</span>
|
|
1538
|
+
</div>
|
|
1539
|
+
);
|
|
1540
|
+
})}
|
|
1541
|
+
</>
|
|
1542
|
+
)}
|
|
1543
|
+
|
|
1544
|
+
{/* Empty state */}
|
|
1545
|
+
{runners.length === 0 && !isLoading && (
|
|
1546
|
+
<p className="py-3 text-center text-xs text-muted-foreground">
|
|
1547
|
+
No runners registered. Use the CLI or desktop app to start one.
|
|
1548
|
+
</p>
|
|
1549
|
+
)}
|
|
1550
|
+
|
|
1551
|
+
{/* Loading state */}
|
|
1552
|
+
{isLoading && (
|
|
1553
|
+
<div className="py-3 text-center text-xs text-muted-foreground">
|
|
1554
|
+
Loading runners...
|
|
1555
|
+
</div>
|
|
1556
|
+
)}
|
|
1557
|
+
|
|
1558
|
+
{/* Hint */}
|
|
1559
|
+
<p className="px-2 pt-1 text-[0.6rem] leading-relaxed text-muted-foreground">
|
|
1560
|
+
Default assigns a cloud runner automatically. Select a specific runner to execute on your own machine.
|
|
1561
|
+
</p>
|
|
1562
|
+
</div>
|
|
1563
|
+
);
|
|
1564
|
+
}
|
package/src/composer/icons.tsx
CHANGED
|
@@ -207,6 +207,33 @@ export function SecretsIcon() {
|
|
|
207
207
|
);
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
export function RunnerIcon() {
|
|
211
|
+
return (
|
|
212
|
+
<svg
|
|
213
|
+
width="14"
|
|
214
|
+
height="14"
|
|
215
|
+
viewBox="0 0 24 24"
|
|
216
|
+
fill="none"
|
|
217
|
+
stroke="currentColor"
|
|
218
|
+
strokeWidth="1.5"
|
|
219
|
+
strokeLinecap="round"
|
|
220
|
+
strokeLinejoin="round"
|
|
221
|
+
aria-hidden="true"
|
|
222
|
+
>
|
|
223
|
+
<rect x="4" y="4" width="16" height="16" rx="2" />
|
|
224
|
+
<rect x="9" y="9" width="6" height="6" />
|
|
225
|
+
<path d="M15 2v2" />
|
|
226
|
+
<path d="M15 20v2" />
|
|
227
|
+
<path d="M2 15h2" />
|
|
228
|
+
<path d="M2 9h2" />
|
|
229
|
+
<path d="M20 15h2" />
|
|
230
|
+
<path d="M20 9h2" />
|
|
231
|
+
<path d="M9 2v2" />
|
|
232
|
+
<path d="M9 20v2" />
|
|
233
|
+
</svg>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
210
237
|
/** Horizontal sliders icon -- signals "configuration" without conflating with "add content." */
|
|
211
238
|
export function ConfigureIcon() {
|
|
212
239
|
return (
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
4
3
|
import type { Environment } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
|
|
5
4
|
import type { ResourceRef } from "@stigmer/sdk";
|
|
6
5
|
import { useStigmer } from "../hooks";
|
|
7
|
-
import {
|
|
6
|
+
import { useFetch } from "../internal/useFetch";
|
|
8
7
|
|
|
9
8
|
/** Return value of {@link useEnvironment}. */
|
|
10
9
|
export interface UseEnvironmentReturn {
|
|
@@ -12,6 +11,8 @@ export interface UseEnvironmentReturn {
|
|
|
12
11
|
readonly environment: Environment | null;
|
|
13
12
|
/** `true` while the initial fetch or a refetch is in flight. */
|
|
14
13
|
readonly isLoading: boolean;
|
|
14
|
+
/** `true` while a background refetch is in flight and stale data is shown. */
|
|
15
|
+
readonly isRefetching: boolean;
|
|
15
16
|
/** Error from the last failed request, or `null` when healthy. */
|
|
16
17
|
readonly error: Error | null;
|
|
17
18
|
/** Discard cached data and re-fetch the environment from the server. */
|
|
@@ -49,46 +50,21 @@ export function useEnvironment(
|
|
|
49
50
|
ref: ResourceRef | null,
|
|
50
51
|
): UseEnvironmentReturn {
|
|
51
52
|
const stigmer = useStigmer();
|
|
52
|
-
const [environment, setEnvironment] = useState<Environment | null>(null);
|
|
53
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
54
|
-
const [error, setError] = useState<Error | null>(null);
|
|
55
|
-
const [fetchKey, setFetchKey] = useState(0);
|
|
56
|
-
|
|
57
|
-
const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
|
|
58
53
|
|
|
59
54
|
const org = ref?.org;
|
|
60
55
|
const slug = ref?.slug;
|
|
61
56
|
const version = ref?.version;
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
setError(null);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const cancelled = { current: false };
|
|
72
|
-
setIsLoading(true);
|
|
73
|
-
setError(null);
|
|
74
|
-
|
|
75
|
-
stigmer.environment.getByReference({ org, slug, version }).then(
|
|
76
|
-
(result) => {
|
|
77
|
-
if (cancelled.current) return;
|
|
78
|
-
setEnvironment(result);
|
|
79
|
-
setIsLoading(false);
|
|
80
|
-
},
|
|
81
|
-
(err) => {
|
|
82
|
-
if (cancelled.current) return;
|
|
83
|
-
setError(toError(err));
|
|
84
|
-
setIsLoading(false);
|
|
85
|
-
},
|
|
86
|
-
);
|
|
58
|
+
const fetchFn =
|
|
59
|
+
org && slug
|
|
60
|
+
? () => stigmer.environment.getByReference({ org, slug, version })
|
|
61
|
+
: null;
|
|
87
62
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
63
|
+
const { data: environment, isLoading, isRefetching, error, refetch } = useFetch(
|
|
64
|
+
fetchFn,
|
|
65
|
+
[org, slug, version, stigmer],
|
|
66
|
+
null,
|
|
67
|
+
);
|
|
92
68
|
|
|
93
|
-
return { environment, isLoading, error, refetch };
|
|
69
|
+
return { environment, isLoading, isRefetching, error, refetch };
|
|
94
70
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useRef } from "react";
|
|
4
4
|
import { create } from "@bufbuild/protobuf";
|
|
5
5
|
import type { Environment } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
|
|
6
6
|
import { ListEnvironmentsRequestSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/io_pb";
|
|
7
7
|
import { useStigmer } from "../hooks";
|
|
8
|
-
import {
|
|
8
|
+
import { useFetch } from "../internal/useFetch";
|
|
9
9
|
|
|
10
10
|
/** Return value of {@link useEnvironmentList}. */
|
|
11
11
|
export interface UseEnvironmentListReturn {
|
|
@@ -15,6 +15,8 @@ export interface UseEnvironmentListReturn {
|
|
|
15
15
|
readonly totalCount: number;
|
|
16
16
|
/** `true` while the initial fetch or a refetch is in flight. */
|
|
17
17
|
readonly isLoading: boolean;
|
|
18
|
+
/** `true` while a background refetch is in flight and stale data is shown. */
|
|
19
|
+
readonly isRefetching: boolean;
|
|
18
20
|
/** Error from the last failed request, or `null` when healthy. */
|
|
19
21
|
readonly error: Error | null;
|
|
20
22
|
/** Discard cached data and re-fetch the list from the server. */
|
|
@@ -47,30 +49,6 @@ export function useEnvironmentList(
|
|
|
47
49
|
labels?: Record<string, string>,
|
|
48
50
|
): UseEnvironmentListReturn {
|
|
49
51
|
const stigmer = useStigmer();
|
|
50
|
-
const [environments, setEnvironments] = useState<Environment[]>([]);
|
|
51
|
-
const [totalCount, setTotalCount] = useState(0);
|
|
52
|
-
const [isLoading, setIsLoading] = useState(!!org);
|
|
53
|
-
const [error, setError] = useState<Error | null>(null);
|
|
54
|
-
const [fetchKey, setFetchKey] = useState(0);
|
|
55
|
-
|
|
56
|
-
// Synchronously reset loading state when org changes so that
|
|
57
|
-
// downstream hooks see isLoading=true in the SAME render —
|
|
58
|
-
// not deferred to the next render via an effect.
|
|
59
|
-
const [prevOrg, setPrevOrg] = useState(org);
|
|
60
|
-
if (org !== prevOrg) {
|
|
61
|
-
setPrevOrg(org);
|
|
62
|
-
if (org) {
|
|
63
|
-
setIsLoading(true);
|
|
64
|
-
setEnvironments([]);
|
|
65
|
-
setTotalCount(0);
|
|
66
|
-
setError(null);
|
|
67
|
-
} else {
|
|
68
|
-
setIsLoading(false);
|
|
69
|
-
setEnvironments([]);
|
|
70
|
-
setTotalCount(0);
|
|
71
|
-
setError(null);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
52
|
|
|
75
53
|
const labelsRef = useRef(labels);
|
|
76
54
|
if (
|
|
@@ -81,38 +59,33 @@ export function useEnvironmentList(
|
|
|
81
59
|
}
|
|
82
60
|
const stableLabels = labelsRef.current;
|
|
83
61
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.then(
|
|
99
|
-
(result) => {
|
|
100
|
-
if (cancelled.current) return;
|
|
101
|
-
setEnvironments(result.items);
|
|
102
|
-
setTotalCount(result.totalCount);
|
|
103
|
-
setIsLoading(false);
|
|
104
|
-
},
|
|
105
|
-
(err) => {
|
|
106
|
-
if (cancelled.current) return;
|
|
107
|
-
setError(toError(err));
|
|
108
|
-
setIsLoading(false);
|
|
109
|
-
},
|
|
110
|
-
);
|
|
62
|
+
const fetchFn = org
|
|
63
|
+
? async () => {
|
|
64
|
+
const result = await stigmer.environment.list(
|
|
65
|
+
create(ListEnvironmentsRequestSchema, {
|
|
66
|
+
org,
|
|
67
|
+
labels: stableLabels ?? {},
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
return {
|
|
71
|
+
environments: result.items as Environment[],
|
|
72
|
+
totalCount: result.totalCount,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
: null;
|
|
111
76
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
77
|
+
const { data, isLoading, isRefetching, error, refetch } = useFetch(
|
|
78
|
+
fetchFn,
|
|
79
|
+
[org, stableLabels, stigmer],
|
|
80
|
+
{ environments: [] as Environment[], totalCount: 0 },
|
|
81
|
+
);
|
|
116
82
|
|
|
117
|
-
return {
|
|
83
|
+
return {
|
|
84
|
+
environments: data.environments,
|
|
85
|
+
totalCount: data.totalCount,
|
|
86
|
+
isLoading,
|
|
87
|
+
isRefetching,
|
|
88
|
+
error,
|
|
89
|
+
refetch,
|
|
90
|
+
};
|
|
118
91
|
}
|
|
@@ -487,7 +487,7 @@ function FileContentStateView({
|
|
|
487
487
|
readonly content: string | null;
|
|
488
488
|
readonly contentType: string | null;
|
|
489
489
|
readonly isLoading: boolean;
|
|
490
|
-
readonly error:
|
|
490
|
+
readonly error: Error | null;
|
|
491
491
|
readonly isTruncated: boolean;
|
|
492
492
|
}) {
|
|
493
493
|
if (isLoading) {
|
|
@@ -509,7 +509,7 @@ function FileContentStateView({
|
|
|
509
509
|
return (
|
|
510
510
|
<div className="flex flex-col items-center justify-center gap-2 p-8 text-center">
|
|
511
511
|
<ErrorAlertIcon />
|
|
512
|
-
<p className="text-sm text-destructive">{error}</p>
|
|
512
|
+
<p className="text-sm text-destructive">{error.message}</p>
|
|
513
513
|
</div>
|
|
514
514
|
);
|
|
515
515
|
}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
3
|
import { create } from "@bufbuild/protobuf";
|
|
5
4
|
import { GetArtifactContentRequestSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
|
|
6
5
|
import { useStigmer } from "../hooks";
|
|
6
|
+
import { useFetch } from "../internal/useFetch";
|
|
7
|
+
|
|
8
|
+
interface ArtifactContentData {
|
|
9
|
+
content: string | null;
|
|
10
|
+
contentType: string | null;
|
|
11
|
+
isTruncated: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const EMPTY_ARTIFACT: ArtifactContentData = {
|
|
15
|
+
content: null,
|
|
16
|
+
contentType: null,
|
|
17
|
+
isTruncated: false,
|
|
18
|
+
};
|
|
7
19
|
|
|
8
20
|
/** Return value of {@link useArtifactContent}. */
|
|
9
21
|
export interface UseArtifactContentReturn {
|
|
@@ -31,8 +43,11 @@ export interface UseArtifactContentReturn {
|
|
|
31
43
|
/** `true` while the content request is in-flight. */
|
|
32
44
|
readonly isLoading: boolean;
|
|
33
45
|
|
|
34
|
-
/**
|
|
35
|
-
readonly
|
|
46
|
+
/** `true` while a background refetch is in flight. */
|
|
47
|
+
readonly isRefetching: boolean;
|
|
48
|
+
|
|
49
|
+
/** Error from the last failed attempt, or `null` when healthy. */
|
|
50
|
+
readonly error: Error | null;
|
|
36
51
|
|
|
37
52
|
/**
|
|
38
53
|
* Re-fetch the artifact content. Uses the `fetchKey` counter pattern
|
|
@@ -130,66 +145,34 @@ export function useArtifactContent(
|
|
|
130
145
|
): UseArtifactContentReturn {
|
|
131
146
|
const stigmer = useStigmer();
|
|
132
147
|
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
)
|
|
164
|
-
.then(
|
|
165
|
-
(result) => {
|
|
166
|
-
if (cancelled.current) return;
|
|
167
|
-
|
|
168
|
-
const decoded = new TextDecoder().decode(result.content);
|
|
169
|
-
setContent(decoded);
|
|
170
|
-
setContentType(result.contentType || null);
|
|
171
|
-
setIsTruncated(result.truncated);
|
|
172
|
-
setIsLoading(false);
|
|
173
|
-
},
|
|
174
|
-
(err) => {
|
|
175
|
-
if (cancelled.current) return;
|
|
176
|
-
|
|
177
|
-
setError(
|
|
178
|
-
err instanceof Error
|
|
179
|
-
? err.message
|
|
180
|
-
: "Failed to load artifact content",
|
|
181
|
-
);
|
|
182
|
-
setContent(null);
|
|
183
|
-
setContentType(null);
|
|
184
|
-
setIsTruncated(false);
|
|
185
|
-
setIsLoading(false);
|
|
186
|
-
},
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
return () => {
|
|
190
|
-
cancelled.current = true;
|
|
191
|
-
};
|
|
192
|
-
}, [executionId, storageKey, entryPath, contentHash, stigmer, fetchKey]);
|
|
193
|
-
|
|
194
|
-
return { content, contentType, isTruncated, isLoading, error, refetch };
|
|
148
|
+
const { data, isLoading, isRefetching, error, refetch } = useFetch(
|
|
149
|
+
executionId && storageKey
|
|
150
|
+
? () =>
|
|
151
|
+
stigmer.agentExecution
|
|
152
|
+
.getArtifactContent(
|
|
153
|
+
create(GetArtifactContentRequestSchema, {
|
|
154
|
+
executionId,
|
|
155
|
+
storageKey,
|
|
156
|
+
...(entryPath ? { entryPath } : {}),
|
|
157
|
+
}),
|
|
158
|
+
)
|
|
159
|
+
.then((result): ArtifactContentData => ({
|
|
160
|
+
content: new TextDecoder().decode(result.content),
|
|
161
|
+
contentType: result.contentType || null,
|
|
162
|
+
isTruncated: result.truncated,
|
|
163
|
+
}))
|
|
164
|
+
: null,
|
|
165
|
+
[executionId, storageKey, entryPath, contentHash, stigmer],
|
|
166
|
+
EMPTY_ARTIFACT,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
content: data.content,
|
|
171
|
+
contentType: data.contentType,
|
|
172
|
+
isTruncated: data.isTruncated,
|
|
173
|
+
isLoading,
|
|
174
|
+
isRefetching,
|
|
175
|
+
error,
|
|
176
|
+
refetch,
|
|
177
|
+
};
|
|
195
178
|
}
|