Below is something posted on Mathgroup by Jason McKenzie Alexander. I made a few tiny changes and corresponded about this with Jason for a short while. He sent me his final version, which I post here with his permission. The original (linked above) is really only a few lines of code and can be studied to grasp the principle. The code below is a full package.

BeginPackage["Inspector`"]
StateInspector::usage="Create a dynamic state inspector for the Global` context.";
StateInspectorViewer::usage="Show a dynamic state inspector for the Global` context.";
Begin["`Private`"]
AddNewSymbolHook[]:=$NewSymbol=(If[#2=="Global`",
(#1=#2)&[Symbol["Inspector`Variables`"<>#1],False];
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`up"],True];
(*
Much of the time the OwnValues of a symbol isn't interesting,
so the default on whether to show it is False.
*)
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`own"],False];
(#1=#2)&[Symbol["Inspector`Variables`"<>#1<>"`down"],True];
]&);
UpValuesQ[s_String]:=If[ToExpression[s,StandardForm,UpValues]=!={},True,False]
OwnValuesQ[s_String]:=If[ToExpression[s,StandardForm,OwnValues]=!={},True,False]
DownValuesQ[s_String]:=If[ToExpression[s,StandardForm,DownValues]=!={},True,False]
MakeUpValueView[s_String]:=
If[UpValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"UpValues",
Framed[Dynamic[ToExpression[s,StandardForm,UpValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`up]"]
]
]
MakeOwnValueView[s_String]:=
If[OwnValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"OwnValues",
Framed[Dynamic[ToExpression[s,StandardForm,OwnValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`own]"]
]
]
MakeDownValueView[s_String]:=
If[DownValuesQ[s]===False,
ToClobberNull,
OpenerView[
{
"DownValues",
Framed[Dynamic[ToExpression[s,StandardForm,DownValues]],
ImageSize->Scaled[1],Background->White]
},
ToExpression["Dynamic[Inspector`Variables`"<>s<>"`down]"]
]
]
ConstructColumn[s_String]:=If[
UpValuesQ[s]===False&&OwnValuesQ[s]===False&&DownValuesQ[s]===False,
Framed[Dynamic[Symbol[s]],ImageSize->Scaled[1],Background->White],
Column[
DeleteCases[
{
Framed[Dynamic[Symbol[s]],ImageSize->Scaled[1],Background->White],
MakeUpValueView[s],
MakeOwnValueView[s],
MakeDownValueView[s]
},ToClobberNull
]
]
]
StateInspector[]:=(AddNewSymbolHook[];StateInspector["Global`"])
StateInspector[s_String]:=(AddNewSymbolHook[];Dynamic@Refresh[
Grid[
Partition[
(OpenerView[
{
Row[{
Style[#,FontFamily->"Arial"],
Spacer[6],
Button[Style["Clear",10],ToExpression["Clear["<>#<>"]"],Appearance->"Palette"],
Spacer[6],
Button[Style["Remove",10],
ToExpression["Remove["<>#<>","
<>"Inspector`Variables`"<>#<>","
<>"Inspector`Variables`"<>#<>"`up,"
<>"Inspector`Variables`"<>#<>"`own,"
<>"Inspector`Variables`"<>#<>"`down]"],
Appearance->"Palette"
],
(*Button[Style["Remove",10],ToExpression["Remove["<>#<>"]"],Appearance->"Palette"]*)
}],
Inspector`Private`ConstructColumn[#]
},ToExpression["Dynamic[Inspector`Variables`"<>#<>"]"]
]&)/@Names[s<>"*"],3,3,{1,1},{}
],
Alignment->{Left,Baseline},Background->{Automatic,{{RGBColor[0.98996, 0.950057, 0.785382],RGBColor[1, 0.983169, 0.877287]}}},
ItemSize->Scaled[.333]
],
UpdateInterval->1
])
StateInspectorViewer[]:=(AddNewSymbolHook[];StateInspectorViewer["Global`"])
StateInspectorViewer[s_String]:=(AddNewSymbolHook[];CreateDocument@Pane@Column[{
Row[{
Style["Mathematica",Italic,"Title"],
Style[" state inspector","Title"]
}],
Row[{
Style["Context: ","Subtitle"],
Spacer[6],
Style[s,"Subtitle",FontFamily->"Courier"]
}],
Spacer[6],
StateInspector[s]
}])
End[]
EndPackage[]